コード例 #1
0
ファイル: llpngwrapper.cpp プロジェクト: Boy/netbook
// Do transformations to normalize the input to 8-bpp RGBA
void LLPngWrapper::normalizeImage()
{
	//		1. Expand any palettes
	//		2. Convert grayscales to RGB
	//		3. Create alpha layer from transparency
	//		4. Ensure 8-bpp for all images
	//		5. Apply background matte if any
	//		6. Set (or guess) gamma

	if (mColorType == PNG_COLOR_TYPE_PALETTE)
	{
		png_set_palette_to_rgb(mReadPngPtr);
	}
    if (mColorType == PNG_COLOR_TYPE_GRAY && mBitDepth < 8)
	{
		png_set_gray_1_2_4_to_8(mReadPngPtr);
	}
	if (mColorType == PNG_COLOR_TYPE_GRAY
		|| mColorType == PNG_COLOR_TYPE_GRAY_ALPHA)
	{
		png_set_gray_to_rgb(mReadPngPtr);
	}
	if (png_get_valid(mReadPngPtr, mReadInfoPtr, PNG_INFO_tRNS))
	{
		png_set_tRNS_to_alpha(mReadPngPtr);
	}
	if (mBitDepth < 8)
	{
		png_set_packing(mReadPngPtr);
	}
	else if (mBitDepth == 16)
	{
		png_set_strip_16(mReadPngPtr);
	}
	mHasBKGD = png_get_bKGD(mReadPngPtr, mReadInfoPtr, &mBackgroundColor);
	if (mHasBKGD)
	{
		png_set_background(mReadPngPtr, mBackgroundColor,
			PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
	}

#if LL_DARWIN
	const F64 SCREEN_GAMMA = 1.8;
#else
	const F64 SCREEN_GAMMA = 2.2;
#endif

	if (png_get_gAMA(mReadPngPtr, mReadInfoPtr, &mGamma))
	{
		png_set_gamma(mReadPngPtr, SCREEN_GAMMA, mGamma);
	}
	else
	{
		png_set_gamma(mReadPngPtr, SCREEN_GAMMA, 1/SCREEN_GAMMA);
	}
}
コード例 #2
0
ファイル: png_loader.cpp プロジェクト: project-cabal/cabal
//
// Load a texture from a png image
//
bool PngLoader::loadImageIntoBuffer() {
	DEBUG_ENTER_FUNC();

	if (!basicImageLoad()) {
		png_destroy_read_struct(&_pngPtr, &_infoPtr, png_infopp_NULL);
		return false;
	}
	png_set_strip_16(_pngPtr);		// Strip off 16 bit channels in case they occur

	if (_paletteSize) {
		// Copy the palette
		png_colorp srcPal = _infoPtr->palette;
		for (int i = 0; i < _infoPtr->num_palette; i++) {
			unsigned char alphaVal = (i < _infoPtr->num_trans) ? _infoPtr->trans[i] : 0xFF;	// Load alpha if it's there
			_palette->setSingleColorRGBA(i, srcPal->red, srcPal->green, srcPal->blue, alphaVal);
			srcPal++;
		}
	} else {	// Not a palettized image
		if (_colorType == PNG_COLOR_TYPE_GRAY && _bitDepth < 8)
			png_set_gray_1_2_4_to_8(_pngPtr);	// Round up grayscale images
		if (png_get_valid(_pngPtr, _infoPtr, PNG_INFO_tRNS))
			png_set_tRNS_to_alpha(_pngPtr);		// Convert trans channel to alpha for 32 bits

		png_set_add_alpha(_pngPtr, 0xff, PNG_FILLER_AFTER);		// Filler for alpha if none exists
	}

	uint32 rowBytes = png_get_rowbytes(_pngPtr, _infoPtr);

	// there seems to be a bug in libpng where it doesn't increase the rowbytes or the
	// channel even after we add the alpha channel
	if (_channels == 3 && (rowBytes / _width) == 3) {
		_channels = 4;
		rowBytes = _width * _channels;
	}

	PSP_DEBUG_PRINT("rowBytes[%d], channels[%d]\n", rowBytes, _channels);

	unsigned char *line = (unsigned char*) malloc(rowBytes);
	if (!line) {
		png_destroy_read_struct(&_pngPtr, png_infopp_NULL, png_infopp_NULL);
		PSP_ERROR("Couldn't allocate line\n");
		return false;
	}

	for (size_t y = 0; y < _height; y++) {
		png_read_row(_pngPtr, line, png_bytep_NULL);
		_buffer->copyFromRect(line, rowBytes, 0, y, _width, 1);	// Copy into buffer
	}
	free(line);
	png_read_end(_pngPtr, _infoPtr);
	png_destroy_read_struct(&_pngPtr, &_infoPtr, png_infopp_NULL);

	return true;
}
コード例 #3
0
ファイル: pikl_png.c プロジェクト: t08039/PhotoLibrary
//=============================================================================
// load_png
//=============================================================================
int load_png(PKLImage pkl, FILE *image)
{
	png_structp png_ptr;
	png_infop   info_ptr;
	int i;
	
	png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
	if(!png_ptr) return(1);
	
	info_ptr = png_create_info_struct(png_ptr);
	if(!info_ptr){
		png_destroy_read_struct(&png_ptr, NULL, NULL);
		return(1);
	}

	if( setjmp(png_jmpbuf(png_ptr)) ){
		png_destroy_info_struct(png_ptr, &info_ptr);
		png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
		return(1);
	}

	png_init_io(png_ptr, image);
	png_read_info(png_ptr, info_ptr);
	pkl->width   = info_ptr->width;
	pkl->height  = info_ptr->height;
	pkl->color   = color_pn2pk(info_ptr->color_type);
	pkl->channel = pkl_png_channels(pkl->color);
	pkl->resh = resolution_p2p(info_ptr->phys_unit_type, info_ptr->x_pixels_per_unit);
	pkl->resv = resolution_p2p(info_ptr->phys_unit_type, info_ptr->y_pixels_per_unit);
	if(pkl->color == PKL_UNKNOWN) return(1);

	pkl->image = malloc(pkl->width * pkl->height * pkl->channel);
	if(!pkl->image) return(1);

	if(info_ptr->color_type==PNG_COLOR_TYPE_RGB_ALPHA  ||
	   info_ptr->color_type==PNG_COLOR_TYPE_GRAY_ALPHA || info_ptr->num_trans) png_set_strip_alpha(png_ptr);
	if(info_ptr->bit_depth<8 &&
	   info_ptr->color_type==PNG_COLOR_TYPE_GRAY) png_set_gray_1_2_4_to_8(png_ptr);
	if(info_ptr->bit_depth==16) png_set_strip_16(png_ptr);
	if(info_ptr->color_type==PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png_ptr);

	for(i=0; i<pkl->height; i++)
		png_read_row(png_ptr, &pkl->image[i*pkl->width*pkl->channel], NULL);
	
	png_destroy_info_struct(png_ptr, &info_ptr);
	png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
	
	return(0);
}
コード例 #4
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);
}
コード例 #5
0
ファイル: gstgcs.c プロジェクト: miguelao/gst_plugins_tsunami
gboolean read_png(curlMemoryStructGCS *chunk, unsigned char **raw_image, picSrcImageInfoGCS *info, char *errBuf) 
{
		
  png_structp png_ptr;
  png_infop info_ptr;
  /* initialize stuff */
  png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);

  if (!png_ptr) {
    GST_DEBUG("png_create_read_struct failed");
    strcpy(errBuf, "read_png - Error : png_create_read_struct failed");
    return FALSE;
  }
  info_ptr = png_create_info_struct(png_ptr);
  if (!info_ptr) {
    GST_DEBUG("png_create_info_struct failed"); 
    strcpy(errBuf, "read_png - Error : png_create_info_struct failed");
    return FALSE; 
  }
  FILE* memstream = fmemopen((void *)chunk->memory, chunk->size, "rb");
  if (!memstream) {
    GST_DEBUG("fmemopen failed"); 
    strcpy(errBuf, "read_imgheader - Error : fmemopen failed");
    return FALSE; 
  }		  
  png_init_io(png_ptr, memstream);
		  
  png_set_error_fn(png_ptr, (png_voidp)NULL,  png_error_fn, png_warning_fn);

		 
  /* read file */
  if (setjmp(png_jmpbuf(png_ptr))) {
    sprintf(errBuf, "read_png - Error : %s", "undetermined"); 
    fclose(memstream);
    return FALSE;
  }
		  
       
  png_uint_32 imgWidth, imgHeight;
  int bitdepth, color_type;
		 
  png_read_info(png_ptr, info_ptr);
  png_get_IHDR( png_ptr, info_ptr, &imgWidth, &imgHeight,
                &bitdepth, &color_type, 0, 0, 0 );		  
  //Number of channels
  int channels   = png_get_channels(png_ptr, info_ptr);
		 
  switch (color_type) {
  case PNG_COLOR_TYPE_PALETTE:
    png_set_palette_to_rgb(png_ptr);
    channels = 3;
    info->colorspace =  COLOR_TYPE_GCS_RGB;          
    break;
  case PNG_COLOR_TYPE_GRAY:
    if (bitdepth < 8)
      png_set_gray_1_2_4_to_8(png_ptr);
    //And the bitdepth info
    bitdepth = 8;
    png_set_gray_to_rgb(png_ptr);
    info->colorspace =  COLOR_TYPE_GCS_RGB;       
    break;
  }
  /*if the image has a transperancy set.. convert it to a full Alpha channel..*/
  if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
    png_set_tRNS_to_alpha(png_ptr);
    channels+=1;
    info->colorspace =  COLOR_TYPE_GCS_RGB_ALPHA;   
  }
  //We don't support 16 bit precision.. so if the image Has 16 bits per channel
  //precision... round it down to 8.
  if (bitdepth == 16)
    png_set_strip_16(png_ptr);
		  
  info->width	 = imgWidth;
  info->height   = imgHeight;
  info->channels = channels;
		   	
		  
  /* read file */
  if (setjmp(png_jmpbuf(png_ptr))) {
    sprintf(errBuf, "read_png - Error : %s", "undetermined");
    fclose(memstream);
    return FALSE;
  }
		  
		   
  png_bytep* rowPtrs[imgHeight];
         
			
         
			
  *raw_image = (unsigned char*)malloc(imgWidth * imgHeight * bitdepth * channels / 8);
  const unsigned int stride = imgWidth * bitdepth * channels / 8;
  GST_DEBUG("imgWidth:%d, imgHeight:%d, bitdepth:%d, channels:%d, stride:%d", imgWidth,imgHeight,bitdepth,channels, stride  );
  size_t i;
  for (i = 0; i < imgHeight; i++) {         	
    rowPtrs[i] = (png_bytep*)((png_bytep)(*raw_image) + ( i  * stride));

  }
  png_read_image(png_ptr, (png_bytepp)rowPtrs);
  fclose(memstream);
  return TRUE;
}
コード例 #6
0
int load_png( char *file_name, int stype )
{
	char buf[PNG_BYTES_TO_CHECK], *mess;
	unsigned char *rgb, *rgb2, *rgb3;
	int i, row, do_prog, bit_depth, color_type, interlace_type, width, height;
	unsigned int sig_read = 0;
	FILE *fp;
	png_bytep *row_pointers, trans;
	png_color_16p trans_rgb;

	png_structp png_ptr;
	png_infop info_ptr;
	png_uint_32 pwidth, pheight;
	png_colorp png_palette;

	if ((fp = fopen(file_name, "rb")) == NULL) return -1;
	i = fread(buf, 1, PNG_BYTES_TO_CHECK, fp);
	if ( i != PNG_BYTES_TO_CHECK ) goto fail;
	i = !png_sig_cmp(buf, (png_size_t)0, PNG_BYTES_TO_CHECK);
	if ( i<=0 ) goto fail;
	rewind( fp );

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

	if (png_ptr == NULL) goto fail;

	info_ptr = png_create_info_struct(png_ptr);
	if (info_ptr == NULL)
	{
		png_destroy_read_struct(&png_ptr, NULL, NULL);
		goto fail;
	}

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

	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, &pwidth, &pheight, &bit_depth, &color_type,
		&interlace_type, NULL, NULL);

	width = (int) pwidth;
	height = (int) pheight;

	if ( width > MAX_WIDTH || height > MAX_HEIGHT )
	{
		png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
		fclose(fp);
		return TOO_BIG;
	}

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

	if (setjmp(png_jmpbuf(png_ptr)))	// If libpng generates an error now, clean up
	{
		png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
		fclose(fp);
		free(row_pointers);
		return FILE_LIB_ERROR;
	}

	rgb = NULL;
	mess = NULL;
	if ( width*height > FILE_PROGRESS ) do_prog = 1;
	else do_prog = 0;

	if ( stype == 0 )
	{
		mess = _("Loading PNG image");
		rgb = mem_image;
	}
	if ( stype == 1 )
	{
		mess = _("Loading clipboard image");
		rgb = mem_clipboard;
		if ( rgb != NULL ) free( rgb );		// Lose old clipboard
		mem_clip_mask_clear();			// Lose old clipboard mask
	}

	if ( color_type != PNG_COLOR_TYPE_PALETTE || bit_depth>8 )	// RGB PNG file
	{
		png_set_strip_16(png_ptr);
		png_set_gray_1_2_4_to_8(png_ptr);
		png_set_palette_to_rgb(png_ptr);
		png_set_gray_to_rgb(png_ptr);

		if ( stype == 0 )
		{
			mem_pal_copy( mem_pal, mem_pal_def );
			mem_cols = 256;
			if ( mem_new( width, height, 3 ) != 0 ) goto file_too_huge;
			rgb = mem_image;
			if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
			{
				// Image has a transparent index
				png_get_tRNS(png_ptr, info_ptr, 0, 0, &trans_rgb);
				mem_pal[255].red = trans_rgb->red;
				mem_pal[255].green = trans_rgb->green;
				mem_pal[255].blue = trans_rgb->blue;
				if (color_type == PNG_COLOR_TYPE_GRAY)
				{
					if ( bit_depth==4 ) i = trans_rgb->gray * 17;
					if ( bit_depth==8 ) i = trans_rgb->gray;
					if ( bit_depth==16 ) i = trans_rgb->gray >> (bit_depth-8);
					mem_pal[255].red = i;
					mem_pal[255].green = i;
					mem_pal[255].blue = i;
				}
				mem_xpm_trans = 255;
			}
		}
コード例 #7
0
ファイル: loadpng.c プロジェクト: 0-14N/NDroid
void *readpng(const unsigned char *base, size_t   size, unsigned *_width, unsigned *_height)
{
    PngReader  reader;
    unsigned char *data = 0;
    unsigned char **rowptrs = 0;
    png_structp p = 0;
    png_infop pi = 0;

    png_uint_32 width, height;
    int bitdepth, colortype, imethod, cmethod, fmethod, i;

    p = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
    if(p == 0) {
        LOG("%s: failed to allocate png read struct\n", fn);
        return 0;
    }

    pi = png_create_info_struct(p);
    if(pi == 0) {
        LOG("%s: failed to allocate png info struct\n", fn);
        goto oops;
    }

    reader.base   = base;
    reader.end    = base + size;
    reader.cursor = base;

    if(size < 8 || png_sig_cmp((unsigned char*)base, 0, 8)) {
        LOG("%s: header is not a PNG header\n", fn);
        goto oops;
    }

    reader.cursor += 8;

    if(setjmp(png_jmpbuf(p))) {
        LOG("%s: png library error\n", fn);
    oops:
        png_destroy_read_struct(&p, &pi, 0);
        if(data != 0) free(data);
        if(rowptrs != 0) free(rowptrs);
        return 0;
    }

    png_set_read_fn (p, &reader, png_reader_read_data);
    png_set_sig_bytes(p, 8);

    png_read_info(p, pi);

    png_get_IHDR(p, pi, &width, &height, &bitdepth, &colortype,
                 &imethod, &cmethod, &fmethod);
//    printf("PNG: %d x %d (d=%d, c=%d)\n",
//           width, height, bitdepth, colortype);

    switch(colortype){
    case PNG_COLOR_TYPE_PALETTE:
        png_set_palette_to_rgb(p);
        break;

    case PNG_COLOR_TYPE_RGB:
        if(png_get_valid(p, pi, PNG_INFO_tRNS)) {
            png_set_tRNS_to_alpha(p);
        } else {
            png_set_filler(p, 0xff, PNG_FILLER_AFTER);
        }
        break;

    case PNG_COLOR_TYPE_RGB_ALPHA:
        break;

    case PNG_COLOR_TYPE_GRAY:
        if(bitdepth < 8) {
            png_set_gray_1_2_4_to_8(p);
        }

    default:
        LOG("%s: unsupported (grayscale?) color type\n");
        goto oops;
    }

    if(bitdepth == 16) {
        png_set_strip_16(p);
    }

    data    = (unsigned char*) malloc((width * 4) * height);
    rowptrs = (unsigned char **) malloc(sizeof(unsigned char*) * height);

    if((data == 0) || (rowptrs == 0)){
        LOG("could not allocate data buffer\n");
        goto oops;
    }

    for(i = 0; i < height; i++) {
        rowptrs[i] = data + ((width * 4) * i);
    }

    png_read_image(p, rowptrs);

    png_destroy_read_struct(&p, &pi, 0);
    if(rowptrs != 0) free(rowptrs);

    *_width = width;
    *_height = height;

    return (void*) data;    
}
コード例 #8
0
ファイル: PNGImage.c プロジェクト: cdcarter/io
void PNGImage_load(PNGImage *self)
{
	png_structp png_ptr;
	png_infop info_ptr;
	int bit_depth;
	int color_type;
	int interlace_type;
	png_uint_32 w;
	png_uint_32 h;
	int palleteComponents = 3;

	int number_passes, row;
	FILE *fp = fopen(self->path, "rb");
	PNGImage_error_(self, "");

	if (!fp)
	{
		PNGImage_error_(self, "file not found");
		return;
	}

	/* Create and initialize the png_struct with the desired error handler
		* functions.  If you want to use the default stderr and longjump method,
	* you can supply NULL for the last three parameters.  We also supply the
		* the compiler header file version, so that we know if the application
		* was compiled with a compatible version of the library.  REQUIRED
		*/
	png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);

	if (png_ptr == NULL)
	{
		fclose(fp);
		PNGImage_error_(self, "unable to read png from file");
		return;
	}

	/* Allocate/initialize the memory for image information.  REQUIRED. */
	info_ptr = png_create_info_struct(png_ptr);

	if (info_ptr == NULL)
	{
		fclose(fp);
		png_destroy_read_struct(&(png_ptr), png_infopp_NULL, png_infopp_NULL);
		PNGImage_error_(self, "error allocating png struct");
		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_ptr)))
	{
		/* Free all of the memory associated with the png_ptr and info_ptr */
		png_destroy_read_struct(&(png_ptr), &(info_ptr), png_infopp_NULL);
		fclose(fp);
		PNGImage_error_(self, self->path);
		return;
	}

	/* Set up the input control if you are using standard C streams */
	png_init_io(png_ptr, fp);
	png_read_info(png_ptr, info_ptr);

	png_get_IHDR(png_ptr, info_ptr, &w, &h, &(bit_depth),
				 &(color_type), &(interlace_type), int_p_NULL, int_p_NULL);

	self->width  = w;
	self->height = h;

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


	/* Extract multiple pixels with bit depths of 1, 2, and 4 from a single
		* byte into separate bytes (useful for paletted and grayscale images).
		*/
	png_set_packing(png_ptr);

	/* Expand paletted colors into true RGB triplets */
	/*
	 if (color_type == PNG_COLOR_TYPE_PALETTE)
	 png_set_palette_rgb(png_ptr);
	 */

	/* 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_ptr);

	/* 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_ptr, info_ptr, PNG_INFO_tRNS))
	{
		png_set_tRNS_to_alpha(png_ptr);
		palleteComponents = 4;
	}

	/* swap bytes of 16 bit files to least significant byte first */
	/*png_set_swap(png_ptr);*/

	/* Add filler (or alpha) byte (before/after each RGB triplet) */
	/*png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);*/

	/* Turn on interlace handling.  REQUIRED if you are not using
		* png_read_image().  To see how to handle interlacing passes,
		* see the png_read_row() method below:
		*/
	number_passes = png_set_interlace_handling(png_ptr);

	/* Allocate the memory to hold the image using the fields of info_ptr. */

	/* The easiest way to read the image: */
	{
		/*png_bytep row_pointers[height];*/
		png_bytep *row_pointers = (png_bytep *)malloc(self->height*sizeof(void *));

		for (row = 0; row < self->height; row++)
		{
			/*int bpr = png_get_rowbytes(png_ptr, info_ptr);*/
			int bpr = png_get_rowbytes(png_ptr, info_ptr) * 4;
			row_pointers[row] = png_malloc(png_ptr, bpr);
		}

		/* Now it's time to read the image.  One of these methods is REQUIRED */
		png_read_image(png_ptr, row_pointers);

		{
			int bytesPerRow;
			switch(color_type)
			{
				case PNG_COLOR_TYPE_GRAY:
					self->components = 1; break;
				case PNG_COLOR_TYPE_PALETTE:
					self->components = palleteComponents; break;
				case PNG_COLOR_TYPE_RGB:
					self->components = 3; break;
				case PNG_COLOR_TYPE_RGB_ALPHA:
					self->components = 4; break;
				case PNG_COLOR_TYPE_GRAY_ALPHA:
					self->components = 2; break;
			}

			bytesPerRow = self->width * self->components;
			UArray_setSize_(self->byteArray, self->width * self->height * self->components);

			for (row = 0; row < self->height; row++)
			{
				int i = row*(self->width*self->components);
				memcpy((uint8_t *)UArray_bytes(self->byteArray) + i, row_pointers[row], bytesPerRow);
				free(row_pointers[row]);
			}
		}

		free(row_pointers);
	}
	/* read rest of file, and get additional chunks in info_ptr - REQUIRED */
	png_read_end(png_ptr, (info_ptr));

	/* At this point you have read the entire image */

	/* clean up after the read, and free any memory allocated - REQUIRED */
	png_destroy_read_struct(&(png_ptr), &(info_ptr), png_infopp_NULL);

	fclose(fp);
	return;
}
コード例 #9
0
ファイル: PngParser.C プロジェクト: ulyssesrr/carmen_lcad
// ######################################################################
PngParser::PngParser(const char* filename)
  :
  rep(new Rep(filename))
{
  errno = 0;
  rep->file = fopen(filename, "rb");
  if (rep->file == 0) rep->onError("couldn't open file for png reading");

  const size_t nheader = 8;
  png_byte header[nheader];

  if (fread(header, 1, nheader, rep->file) != nheader) rep->onError("short read on png file header");

  int is_png = !png_sig_cmp(header, 0, nheader);
  if (!is_png) rep->onError("file was not a png image file");

  rep->pngPtr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
  if (rep->pngPtr == 0) rep->onError("png_create_read_struct failed");

  rep->infoPtr = png_create_info_struct(rep->pngPtr);
  if (rep->infoPtr == 0) rep->onError("png_create_info_struct failed");

  rep->endPtr = png_create_info_struct(rep->pngPtr);
  if (rep->endPtr == 0) rep->onError("png_create_info_struct failed");

  png_init_io(rep->pngPtr, rep->file);

  png_set_sig_bytes(rep->pngPtr, nheader);

  png_read_info(rep->pngPtr, rep->infoPtr);

  rep->bitDepth = png_get_bit_depth(rep->pngPtr, rep->infoPtr);

  rep->colorType = png_get_color_type(rep->pngPtr, rep->infoPtr);

  if (rep->bitDepth == 16)
    png_set_strip_16(rep->pngPtr);
  else if (rep->bitDepth < 8 && (rep->colorType == PNG_COLOR_TYPE_GRAY))
    png_set_gray_1_2_4_to_8(rep->pngPtr);
  else if (rep->bitDepth != 8 && (rep->colorType != PNG_COLOR_TYPE_PALETTE))
    rep->onError(sformat("invalid bit-depth(%d)/color-mode(%d) "
                         "combination", rep->bitDepth, rep->colorType));

  // Strip out the alpha channel, if present
  if (rep->colorType & PNG_COLOR_MASK_ALPHA)
    png_set_strip_alpha(rep->pngPtr);

  if (rep->colorType & PNG_COLOR_MASK_PALETTE)
    png_set_palette_to_rgb(rep->pngPtr);

  // This must come after any+all transformations are specified
  png_read_update_info(rep->pngPtr, rep->infoPtr);

  // These calls must come after png_read_update_info, so that we get
  // values that reflect any transformations
  rep->width = png_get_image_width(rep->pngPtr, rep->infoPtr);
  rep->height = png_get_image_height(rep->pngPtr, rep->infoPtr);

  rep->rowBytes = png_get_rowbytes(rep->pngPtr, rep->infoPtr);

  rep->numChannels = png_get_channels(rep->pngPtr, rep->infoPtr);

  ASSERT(rep->rowBytes = rep->width*rep->numChannels);

// run-time mmx PNG optimizations (nate)
#if defined(HAVE_PNG_ASM_FLAGS)
  const png_uint_32 flags = png_get_asm_flags(rep->pngPtr);
  const png_uint_32 mask =
    png_get_asm_flagmask(PNG_SELECT_READ | PNG_SELECT_WRITE);
  png_set_asm_flags(rep->pngPtr, flags | mask);
#endif
}
コード例 #10
0
ファイル: gstpngdec.c プロジェクト: JJCG/gst-plugins-good
static GstFlowReturn
gst_pngdec_caps_create_and_set (GstPngDec * pngdec)
{
  GstFlowReturn ret = GST_FLOW_OK;
  GstCaps *caps = NULL, *res = NULL;
  GstPadTemplate *templ = NULL;
  gint bpc = 0, color_type;
  png_uint_32 width, height;

  g_return_val_if_fail (GST_IS_PNGDEC (pngdec), GST_FLOW_ERROR);

  /* Get bits per channel */
  bpc = png_get_bit_depth (pngdec->png, pngdec->info);

  /* We don't handle 16 bits per color, strip down to 8 */
  if (bpc == 16) {
    GST_LOG_OBJECT (pngdec,
        "this is a 16 bits per channel PNG image, strip down to 8 bits");
    png_set_strip_16 (pngdec->png);
  }

  /* Get Color type */
  color_type = png_get_color_type (pngdec->png, pngdec->info);

#if 0
  /* We used to have this HACK to reverse the outgoing bytes, but the problem
   * that originally required the hack seems to have been in ffmpegcolorspace's
   * RGBA descriptions. It doesn't seem needed now that's fixed, but might
   * still be needed on big-endian systems, I'm not sure. J.S. 6/7/2007 */
  if (color_type == PNG_COLOR_TYPE_RGB_ALPHA)
    png_set_bgr (pngdec->png);
#endif

  /* Gray scale converted to RGB and upscaled to 8 bits */
  if ((color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
      (color_type == PNG_COLOR_TYPE_GRAY)) {
    GST_LOG_OBJECT (pngdec, "converting grayscale png to RGB");
    png_set_gray_to_rgb (pngdec->png);
    if (bpc < 8) {              /* Convert to 8 bits */
      GST_LOG_OBJECT (pngdec, "converting grayscale image to 8 bits");
      png_set_gray_1_2_4_to_8 (pngdec->png);
    }
  }

  /* Palette converted to RGB */
  if (color_type == PNG_COLOR_TYPE_PALETTE) {
    GST_LOG_OBJECT (pngdec, "converting palette png to RGB");
    png_set_palette_to_rgb (pngdec->png);
  }

  /* Update the info structure */
  png_read_update_info (pngdec->png, pngdec->info);

  /* Get IHDR header again after transformation settings */

  png_get_IHDR (pngdec->png, pngdec->info, &width, &height,
      &bpc, &pngdec->color_type, NULL, NULL, NULL);

  pngdec->width = width;
  pngdec->height = height;

  GST_LOG_OBJECT (pngdec, "this is a %dx%d PNG image", pngdec->width,
      pngdec->height);

  switch (pngdec->color_type) {
    case PNG_COLOR_TYPE_RGB:
      GST_LOG_OBJECT (pngdec, "we have no alpha channel, depth is 24 bits");
      pngdec->bpp = 24;
      break;
    case PNG_COLOR_TYPE_RGB_ALPHA:
      GST_LOG_OBJECT (pngdec, "we have an alpha channel, depth is 32 bits");
      pngdec->bpp = 32;
      break;
    default:
      GST_ELEMENT_ERROR (pngdec, STREAM, NOT_IMPLEMENTED, (NULL),
          ("pngdec does not support this color type"));
      ret = GST_FLOW_NOT_SUPPORTED;
      goto beach;
  }

  caps = gst_caps_new_simple ("video/x-raw-rgb",
      "width", G_TYPE_INT, pngdec->width,
      "height", G_TYPE_INT, pngdec->height,
      "bpp", G_TYPE_INT, pngdec->bpp,
      "framerate", GST_TYPE_FRACTION, pngdec->fps_n, pngdec->fps_d, NULL);

  templ = gst_static_pad_template_get (&gst_pngdec_src_pad_template);

  res = gst_caps_intersect (caps, gst_pad_template_get_caps (templ));

  gst_caps_unref (caps);
  gst_object_unref (templ);

  if (!gst_pad_set_caps (pngdec->srcpad, res))
    ret = GST_FLOW_NOT_NEGOTIATED;

  GST_DEBUG_OBJECT (pngdec, "our caps %" GST_PTR_FORMAT, res);

  gst_caps_unref (res);

  /* Push a newsegment event */
  if (pngdec->need_newsegment) {
    gst_pad_push_event (pngdec->srcpad,
        gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME, 0, -1, 0));
    pngdec->need_newsegment = FALSE;
  }

beach:
  return ret;
}
コード例 #11
0
unsigned char *	ReadPNG(FILE * fp, unsigned int & sizeX, unsigned int &sizeY, int &img_depth, int &img_color_type, unsigned char *** row_pointer_ptr)
{
	png_structp png_ptr;
	png_bytepp row_pointers;
	png_infop info_ptr;
	int  interlace_type;

	png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, (png_error_ptr)png_cexcept_error, (png_error_ptr)NULL);
	if (png_ptr == NULL)
	{
		exit(1);
		return NULL;
	}
	info_ptr = png_create_info_struct(png_ptr);
	if (info_ptr == NULL)
	{
		png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
		fprintf(stderr,"VSImage ERROR : PNG info_ptr == NULL !!!\n");
		exit(1);
		return NULL;
	}
	if (setjmp(png_jmpbuf(png_ptr)))
	{
		/* Free all of the memory associated with the png_ptr and info_ptr */
		png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
		/* If we get here, we had a problem reading the file */
		exit(1);
		return NULL;
	}

        png_init_io(png_ptr, fp);

	//png_set_sig_bytes(png_ptr, 8);
	png_read_info(png_ptr, info_ptr);  /* read all PNG info up to image data */
	png_get_IHDR(png_ptr, info_ptr, (png_uint_32 *)&sizeX, (png_uint_32 *)&sizeY, &img_depth, &img_color_type, &interlace_type, NULL, NULL);

# if __BYTE_ORDER != __BIG_ENDIAN
	if (img_depth==16)
		png_set_swap (png_ptr);
#endif

	if (img_depth==16)//for now
		png_set_strip_16(png_ptr);
	if (img_color_type == PNG_COLOR_TYPE_PALETTE)
		png_set_palette_to_rgb(png_ptr);
		   
	if (img_color_type == PNG_COLOR_TYPE_GRAY && img_depth < 8)
		png_set_gray_1_2_4_to_8(png_ptr);

	png_set_expand (png_ptr);
	png_read_update_info (png_ptr,info_ptr);
	png_get_IHDR(png_ptr, info_ptr, (png_uint_32 *)&sizeX, (png_uint_32 *)&sizeY, &img_depth, &img_color_type, &interlace_type, NULL, NULL);
	row_pointers = (unsigned char **)malloc (sizeof (unsigned char *) *sizeY);
	int numchan=1;
	if (img_color_type&PNG_COLOR_MASK_COLOR)
		numchan =3;
	if (img_color_type &PNG_COLOR_MASK_PALETTE)
		numchan =1;
	if (img_color_type&PNG_COLOR_MASK_ALPHA)
		numchan++;
	unsigned long stride = numchan*sizeof (unsigned char)*img_depth/8;
	unsigned char * image = (unsigned char *) malloc (stride*sizeX*sizeY);
	for (unsigned int i=0;i<sizeY;i++)
	{
		row_pointers[i] = &image[i*stride*sizeX];
	}
	png_read_image (png_ptr,row_pointers);
	unsigned char * result;
        result = image;
	//free (row_pointers);
        *row_pointer_ptr=row_pointers;
	png_read_end(png_ptr, info_ptr);
	png_destroy_read_struct(&png_ptr, &info_ptr, NULL);

	return result;
}
コード例 #12
0
bool PNGImageFileType::read(      Image        *OSG_PNG_ARG(pImage  ), 
                                  std::istream &OSG_PNG_ARG(is      ),
                            const std::string  &OSG_PNG_ARG(mimetype))
{
#ifdef OSG_WITH_PNG

    bool                retCode;
    Image::PixelFormat  pixelFormat = OSG::Image::OSG_INVALID_PF;
    png_structp         png_ptr;
    png_infop           info_ptr;
    png_uint_32         width, wc, height, h, i, res_x, res_y;
    png_byte            bit_depth, channels, color_type;
    png_bytep           *row_pointers, base;

    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);

    if(!png_ptr)
        return false;

    png_set_error_fn(png_ptr, 0, &errorOutput, &warningOutput);

    info_ptr = png_create_info_struct(png_ptr);

    if(!info_ptr)
    {
        png_destroy_read_struct(&png_ptr, 0, 0);
        return false;
    }

    if(setjmp(png_ptr->jmpbuf))
    {
        png_destroy_read_struct(&png_ptr, &info_ptr, 0);
        return false;
    }

    png_set_read_fn(png_ptr, &is, &isReadFunc);

    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);
    bit_depth = png_get_bit_depth(png_ptr, info_ptr);
    res_x = png_get_x_pixels_per_meter(png_ptr, info_ptr);
    res_y = png_get_y_pixels_per_meter(png_ptr, info_ptr);
    channels = png_get_channels(png_ptr, info_ptr);
    color_type = png_get_color_type(png_ptr, info_ptr);

    // Convert paletted images to RGB
    if (color_type == PNG_COLOR_TYPE_PALETTE)
    {
        png_set_palette_to_rgb(png_ptr);
        channels = 3;
        bit_depth = 8;
    }

    // Convert < 8 bit to 8 bit
    if(color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
    {
        png_set_gray_1_2_4_to_8(png_ptr);
        bit_depth = 8;
    }

#if BYTE_ORDER == LITTLE_ENDIAN
    if (bit_depth == 16)
        png_set_swap(png_ptr);
#endif

    // Add a full alpha channel if there is transparency
    // information in a tRNS chunk
    if(png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
    {
        png_set_tRNS_to_alpha(png_ptr);
        ++channels;
    } 

    Int32 dataType;

    switch (bit_depth) 
    {
        case 8:
            dataType = Image::OSG_UINT8_IMAGEDATA;
            break;
        case 16:
            dataType = Image::OSG_UINT16_IMAGEDATA;
            break;
        default:
            FWARNING (( "Invalid bit_depth: %d, can not read png-data\n",
                        bit_depth ));
            return false;
    }

    switch(channels)
    {
        case 1:
            pixelFormat = Image::OSG_L_PF;
            break;
        case 2:
            pixelFormat = Image::OSG_LA_PF;
            break;
        case 3:
            pixelFormat = Image::OSG_RGB_PF;
            break;
        case 4:
            pixelFormat = Image::OSG_RGBA_PF;
        break;
    };
    
    if(pImage->set(pixelFormat, width, height,
                   1, 1, 1, 0.0, 0,
                   dataType))
    {
        // set resolution png supports only pixel per meter,
        // so we do a conversion to dpi with some rounding.
        res_x = png_uint_32((Real32(res_x) / 39.37007874f) < 0.0f ?
                            (Real32(res_x) / 39.37007874f) - 0.5f :
                            (Real32(res_x) / 39.37007874f) + 0.5f);
        res_y = png_uint_32((Real32(res_y) / 39.37007874f) < 0.0f ?
                            (Real32(res_y) / 39.37007874f) - 0.5f :
                            (Real32(res_y) / 39.37007874f) + 0.5f);

        pImage->setResX(Real32(res_x));
        pImage->setResY(Real32(res_y));
        pImage->setResUnit(Image::OSG_RESUNIT_INCH);

        // Calculate the row pointers
        row_pointers = new png_bytep[height];
        wc = width * channels * (bit_depth / 8);
        h = height - 1;
        base = pImage->editData();

        for(i = 0; i < height; ++i)
            row_pointers[i] = base + (h - i) * wc;

        // Read the image data
        png_read_image(png_ptr, row_pointers);

        delete[] row_pointers;

        retCode = true;
    }
    else
    {
        retCode = false;
    }

    png_destroy_read_struct(&png_ptr, &info_ptr, 0);

    return retCode;

#else

    SWARNING << getMimeType() 
             << " read is not compiled into the current binary " 
             << std::endl;

    return false;

#endif

}
コード例 #13
0
UInt64 PNGImageFileType::restoreData(      Image  *OSG_PNG_ARG  (pImage ),
                                     const UChar8 *OSG_PNG_ARG  (buffer ),
                                           Int32   OSG_CHECK_ARG(memSize))
{
#ifdef OSG_WITH_PNG

    UInt64              retCode;
    Image::PixelFormat  pixelFormat = Image::OSG_INVALID_PF;
    png_structp         png_ptr;
    png_infop           info_ptr;
    png_uint_32         width, wc, height, h, i;
    png_byte            bit_depth, channels, color_type;
    png_bytep           *row_pointers, base;

    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);

    if(!png_ptr)
    {
        return 0;
    }

    png_set_error_fn(png_ptr, 0, &errorOutput, &warningOutput);

    info_ptr = png_create_info_struct(png_ptr);

    if(!info_ptr)
    {
        png_destroy_read_struct(&png_ptr, 0, 0);
        return 0;
    }

    if(setjmp(png_ptr->jmpbuf))
    {
        png_destroy_read_struct(&png_ptr, &info_ptr, 0);
        return 0;
    }

    BufferInfo bufferInfo;
    bufferInfo.buffer = const_cast<UChar8 *>(buffer);
    bufferInfo.length = 0;
    png_set_read_fn(png_ptr, static_cast<void *>(&bufferInfo), user_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);
    bit_depth = png_get_bit_depth(png_ptr, info_ptr);
    channels = png_get_channels(png_ptr, info_ptr);
    color_type = png_get_color_type(png_ptr, info_ptr);

    // Convert paletted images to RGB
    if(color_type == PNG_COLOR_TYPE_PALETTE)
    {
        png_set_palette_to_rgb(png_ptr);
        channels = 3;
        bit_depth = 8;
    }

    // Convert < 8 bit to 8 bit
    if(color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
    {
        png_set_gray_1_2_4_to_8(png_ptr);
        bit_depth = 8;
    }

#if BYTE_ORDER == LITTLE_ENDIAN
    if (bit_depth == 16)
        png_set_swap(png_ptr);
#endif
   
    // Add a full alpha channel if there is transparency
    // information in a tRNS chunk
    if(png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
    {
        png_set_tRNS_to_alpha(png_ptr);
        ++channels;
    }   
                                                                 
    Int32 dataType;

    switch (bit_depth) 
    {
        case 8:
            dataType = Image::OSG_UINT8_IMAGEDATA;
            break;
        case 16:
            dataType = Image::OSG_UINT16_IMAGEDATA;
            break;
        default:
            FWARNING (( "Invalid bit_depth: %d, can not read png-data\n",
                        bit_depth ));
            return false;
    }
    
    switch(channels)
    {
        case 1:
            pixelFormat = Image::OSG_L_PF;
            break;
        case 2:
            pixelFormat = Image::OSG_LA_PF;
            break;
        case 3:
            pixelFormat = Image::OSG_RGB_PF;
            break;
        case 4:
            pixelFormat = Image::OSG_RGBA_PF;
            break;
    };
    
    if(pImage->set(pixelFormat, width, height,
                   1, 1, 1, 0.0, 0,
                   dataType))
    {
        // Calculate the row pointers
        row_pointers = new png_bytep[height];
        wc = width * channels * (bit_depth / 8);
        h = height - 1;
        base = pImage->editData();

        for(i = 0; i < height; ++i)
            row_pointers[i] = base + (h - i) * wc;

        // Read the image data
        png_read_image(png_ptr, row_pointers);
        
        delete[] row_pointers;
        
        retCode = bufferInfo.length;
    }
    else
    {
        retCode = 0;
    }

    png_destroy_read_struct(&png_ptr, &info_ptr, 0);
    
    return retCode;

#else
    SWARNING << getMimeType() 
             << " restoreData is not compiled into the current binary " 
             << std::endl;

    return 0;
#endif
}
コード例 #14
0
ファイル: png.cpp プロジェクト: DerSaidin/DarkRadiant
static RGBAImagePtr LoadPNGBuff (unsigned char* fbuffer)
{
	png_byte** row_pointers;
	png_bytep p_fbuffer;

	p_fbuffer = fbuffer;

	// the reading glue
	// http://www.libpng.org/pub/png/libpng-manual.html

	png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 
						  (png_voidp)NULL, user_error_fn, user_warning_fn);

	if (!png_ptr)
	{
		rError() << "libpng error: png_create_read_struct\n";
		return RGBAImagePtr();
	}

	png_infop info_ptr = png_create_info_struct(png_ptr);

	if (!info_ptr)
	{
		png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
		rError() << "libpng error: png_create_info_struct (info_ptr)" << std::endl;
		return RGBAImagePtr();
	}

	png_infop end_info = png_create_info_struct(png_ptr);

	if (!end_info)
	{
		png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);

		rError() << "libpng error: png_create_info_struct (end_info)" << std::endl;
		return RGBAImagePtr();
	}

	// configure the read function
	png_set_read_fn(png_ptr, (png_voidp)&p_fbuffer, (png_rw_ptr)&user_read_data);

	if (setjmp(png_jmpbuf(png_ptr)))
	{
		png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
		return RGBAImagePtr();
	}

	png_read_info(png_ptr, info_ptr);

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

	// we want to treat all images the same way
	//   The following code transforms grayscale images of less than 8 to 8 bits,
	//   changes paletted images to RGB, and adds a full alpha channel if there is
	//   transparency information in a tRNS chunk.
	if (color_type == PNG_COLOR_TYPE_PALETTE)
	{
		png_set_palette_to_rgb(png_ptr);
	}

	if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
	{
#if PNG_LIBPNG_VER < 10400
		png_set_gray_1_2_4_to_8(png_ptr);
#else
		png_set_expand_gray_1_2_4_to_8(png_ptr);
#endif 
	}

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

	if (!(color_type & PNG_COLOR_MASK_ALPHA))
	{
		// Set the background color to draw transparent and alpha images over.
		png_color_16 my_background, *image_background;

		if (png_get_bKGD(png_ptr, info_ptr, &image_background))
		{
			png_set_background(png_ptr, image_background, PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
		}
		else
		{
			png_set_background(png_ptr, &my_background, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
		}

		// Add alpha byte after each RGB triplet
		png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
	}

	// read the sucker in one chunk
	png_read_update_info(png_ptr, info_ptr);

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

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

	// allocate the pixel buffer, and the row pointers
	RGBAImagePtr image(new RGBAImage(width, height));

	row_pointers = (png_byte**) malloc((height) * sizeof(png_byte*));

	for (int i = 0; i < height; i++)
	{
		row_pointers[i] = (png_byte*)(image->getMipMapPixels(0)) + i * 4 * (width);
	}

	// actual read
	png_read_image(png_ptr, row_pointers);

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

	/* free up the memory structure */
	png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);

	free(row_pointers);

	return image;
}
コード例 #15
0
    /**
     Our implementation of libPNG callbacks
    */
    void haveInfo()
    {
        int bitDepth, colorType, interlaceType;
    
        png_get_IHDR(pngReadStruct, pngInfoStruct, &width, &height, &bitDepth,
                     &colorType, &interlaceType, 0, 0);
                     
        if (!ImageManager::isAcceptableSize(width, height)) {
            libPngError = true;
            return;
        }
        
        //Ask libPNG to change bit depths we don't support
        if (bitDepth < 8)
#if PNG_LIBPNG_VER < 10400
            png_set_gray_1_2_4_to_8(pngReadStruct);
#else
            png_set_expand_gray_1_2_4_to_8(pngReadStruct);
#endif
        
        if (bitDepth > 8)
            png_set_strip_16       (pngReadStruct);
            
        //Some images (basically, only paletted ones) may have alpha
        //included as part of a tRNS chunk. We want to convert that to regular alpha
        //channel..
        bool haveTRNS = false; 
        if (png_get_valid(pngReadStruct, pngInfoStruct, PNG_INFO_tRNS))
        {
            png_set_tRNS_to_alpha(pngReadStruct);
            haveTRNS = true;
            
            if (colorType == PNG_COLOR_TYPE_RGB)
                colorType =  PNG_COLOR_TYPE_RGB_ALPHA; //Paranoia..
            else if (colorType == PNG_COLOR_TYPE_GRAY)
                colorType = PNG_COLOR_TYPE_GRAY_ALPHA;
        }    
            
        ImageFormat imFrm;    
            
        //Prepare for mapping from colorType to our format descriptors.
        switch (colorType)
        {
            case PNG_COLOR_TYPE_GRAY:
                imFrm.greyscaleSetup();
                break;
            case PNG_COLOR_TYPE_GRAY_ALPHA:
                //We don't natively support 8-bit plus alpha, so ask libPNG to expand it out to RGB
                png_set_gray_to_rgb(pngReadStruct);
                imFrm.type = ImageFormat::Image_ARGB_32;
                break;
            case PNG_COLOR_TYPE_PALETTE:                
                //For now, we handle paletted images as RGB or ARGB
                //### TODO: handle non-alpha paletted images with a sufficiently small palette as 
                //paletted
                imFrm.type = haveTRNS ? ImageFormat::Image_ARGB_32 : ImageFormat::Image_RGB_32;
                png_set_palette_to_rgb(pngReadStruct);
                break;
            case PNG_COLOR_TYPE_RGB:
                imFrm.type = ImageFormat::Image_RGB_32;
                break;
            case PNG_COLOR_TYPE_RGB_ALPHA:
                imFrm.type = ImageFormat::Image_ARGB_32;
                break;
            default:
                //Huh?
                libPngError = true;
                return;
        }
        
        //Configure padding/byte swapping if need be (32-bit images)
        //We want a 32-bit value with ARGB.
        //This means that for little-endian, in memory we should have BGRA,
        //and for big-endian, well, ARGB        
        if (imFrm.type == ImageFormat::Image_RGB_32)
        {
            //Need fillers, plus perhaps BGR swapping for non-alpha
#if Q_BYTE_ORDER == Q_BIG_ENDIAN || defined(__BIG_ENDIAN__)
            png_set_filler(pngReadStruct, 0xff, PNG_FILLER_BEFORE);
#else
            png_set_filler(pngReadStruct, 0xff, PNG_FILLER_AFTER);
            png_set_bgr   (pngReadStruct);
#endif                
        }
        else if (imFrm.type == ImageFormat::Image_ARGB_32)
        {
#if Q_BYTE_ORDER == Q_BIG_ENDIAN || defined(__BIG_ENDIAN__)
            png_set_swap_alpha(pngReadStruct); //ARGB, not RGBA
#else
            png_set_bgr   (pngReadStruct);     //BGRA
#endif
        }
        
        //Remember depth, for our own use
        depth = imFrm.depth();
        
        //handle interlacing        
        if (interlaceType != PNG_INTERLACE_NONE)
        {
            interlaced  = true;
            scanlineBuf = new unsigned char[depth * width];
            png_set_interlace_handling(pngReadStruct);
            
            // Give up on premultiply in this case..
            if (imFrm.type == ImageFormat::Image_ARGB_32)
                imFrm.type = ImageFormat::Image_ARGB_32_DontPremult;
        }
        
        notifySingleFrameImage(width, height, imFrm);
        
        //OK, time to start input
        png_read_update_info(pngReadStruct, pngInfoStruct);
    }
コード例 #16
0
Bool
readPng (const char   *filename,
	 char	      **data,
	 unsigned int *width,
	 unsigned int *height)
{
    static const int PNG_SIG_SIZE = 8;
    unsigned char    png_sig[PNG_SIG_SIZE];
    FILE	     *file;
    int		     sig_bytes;
    png_struct	     *png;
    png_info	     *info;
    png_uint_32	     png_width, png_height;
    int	     depth, color_type, interlace, i;
    unsigned int     pixel_size;
    png_byte	     **row_pointers;

    file = fopen (filename, "r");
    if (!file)
    {
	char *home, *imagedir;

	home = getenv ("HOME");
	if (home)
	{
	    imagedir = malloc (strlen (home) +
			       strlen (HOME_IMAGEDIR) +
			       strlen (filename) + 3);
	    if (imagedir)
	    {
		sprintf (imagedir, "%s/%s/%s", home, HOME_IMAGEDIR, filename);
		file = fopen (imagedir, "r");
		free (imagedir);
	    }
	}

	if (!file)
	{
	    imagedir = malloc (strlen (IMAGEDIR) + strlen (filename) + 2);
	    if (imagedir)
	    {
		sprintf (imagedir, "%s/%s", IMAGEDIR, filename);
		file = fopen (imagedir, "r");
		free (imagedir);
	    }

	    if (!file)
		return FALSE;
	}
    }

    sig_bytes = fread (png_sig, 1, PNG_SIG_SIZE, file);
    if (png_check_sig (png_sig, sig_bytes) == 0)
    {
	fclose (file);
	return FALSE;
    }

    png = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    if (!png)
    {
	fclose (file);
	return FALSE;
    }

    info = png_create_info_struct (png);
    if (info == NULL)
    {
	fclose (file);
	png_destroy_read_struct (&png, NULL, NULL);
	return FALSE;
    }

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

    png_read_info (png, info);

    png_get_IHDR (png, info,
		  &png_width, &png_height, &depth,
		  &color_type, &interlace, NULL, NULL);
    *width = png_width;
    *height = png_height;

    /* 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 && depth < 8)
	png_set_gray_1_2_4_to_8 (png);

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

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

    if (depth < 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_bgr (png);
    png_set_filler (png, 0xff, PNG_FILLER_AFTER);

    png_set_read_user_transform_fn (png, premultiplyData);

    png_read_update_info (png, info);

    pixel_size = 4;
    *data = (char *) malloc (png_width * png_height * pixel_size);
    if (*data == NULL)
    {
	fclose (file);
	return FALSE;
    }

    row_pointers = (png_byte **) malloc (png_height * sizeof (char *));
    for (i=0; i < png_height; i++)
	row_pointers[i] = (png_byte *) (*data + i * png_width * pixel_size);

    png_read_image (png, row_pointers);
    png_read_end (png, info);

    free (row_pointers);
    fclose (file);

    png_destroy_read_struct (&png, &info, NULL);

    return TRUE;
}
コード例 #17
0
// load in the image data
IImage* CImageLoaderPng::loadImage(io::IReadFile* file) const
{
#ifdef _IRR_COMPILE_WITH_LIBPNG_
	if (!file)
		return 0;

	video::IImage* image = 0;
	//Used to point to image rows
	u8** RowPointers = 0;

	png_byte buffer[8];
	// Read the first few bytes of the PNG file
	if( file->read(buffer, 8) != 8 )
	{
		os::Printer::log("LOAD PNG: can't read file\n", file->getFileName(), ELL_ERROR);
		return 0;
	}

	// Check if it really is a PNG file
	if( png_sig_cmp(buffer, 0, 8) )
	{
		os::Printer::log("LOAD PNG: not really a png\n", file->getFileName(), ELL_ERROR);
		return 0;
	}

	// Allocate the png read struct
	png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
		NULL, (png_error_ptr)png_cpexcept_error, NULL);
	if (!png_ptr)
	{
		os::Printer::log("LOAD PNG: Internal PNG create read struct failure\n", file->getFileName(), ELL_ERROR);
		return 0;
	}

	// Allocate the png info struct
	png_infop info_ptr = png_create_info_struct(png_ptr);
	if (!info_ptr)
	{
		os::Printer::log("LOAD PNG: Internal PNG create info struct failure\n", file->getFileName(), ELL_ERROR);
		png_destroy_read_struct(&png_ptr, NULL, NULL);
		return 0;
	}

	// for proper error handling
	if (setjmp(png_jmpbuf(png_ptr)))
	{
		png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
		if (RowPointers)
			delete [] RowPointers;
		return 0;
	}

	// changed by zola so we don't need to have public FILE pointers
	png_set_read_fn(png_ptr, file, user_read_data_fcn);

	png_set_sig_bytes(png_ptr, 8); // Tell png that we read the signature

	png_read_info(png_ptr, info_ptr); // Read the info section of the png file

	u32 Width;
	u32 Height;
	s32 BitDepth;
	s32 ColorType;
	{
		// Use temporary variables to avoid passing casted pointers
		png_uint_32 w,h;
		// Extract info
		png_get_IHDR(png_ptr, info_ptr,
			&w, &h,
			&BitDepth, &ColorType, NULL, NULL, NULL);
		Width=w;
		Height=h;
	}

	// Convert palette color to true color
	if (ColorType==PNG_COLOR_TYPE_PALETTE)
		png_set_palette_to_rgb(png_ptr);

	// Convert low bit colors to 8 bit colors
	if (BitDepth < 8)
	{
		if (ColorType==PNG_COLOR_TYPE_GRAY || ColorType==PNG_COLOR_TYPE_GRAY_ALPHA)
#if (PNG_LIBPNG_VER_MAJOR > 1) || (PNG_LIBPNG_VER_MINOR > 3)
			png_set_expand_gray_1_2_4_to_8(png_ptr);
#else
			png_set_gray_1_2_4_to_8(png_ptr);
#endif
		else
			png_set_packing(png_ptr);
	}
コード例 #18
0
bool SkPNGImageDecoder::onDecodeInit(SkStream* sk_stream,
        png_structp *png_ptrp, png_infop *info_ptrp)
{
    /* Create and initialize the png_struct with the desired error handler
    * functions.  If you want to use the default stderr and longjump method,
    * you can supply NULL for the last three parameters.  We also supply the
    * the compiler header file version, so that we know if the application
    * was compiled with a compatible version of the library.  */
    png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
        NULL, sk_error_fn, NULL);
    //   png_voidp user_error_ptr, user_error_fn, user_warning_fn);
    if (png_ptr == NULL) {
        return false;
    }
    *png_ptrp = png_ptr;

    /* Allocate/initialize the memory for image information. */
    png_infop info_ptr = png_create_info_struct(png_ptr);
    if (info_ptr == NULL) {
        png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
        return false;
    }
    *info_ptrp = info_ptr;

    /* 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_ptr))) {
        return false;
    }

    /* If you are using replacement read functions, instead of calling
    * png_init_io() here you would call:
    */
    png_set_read_fn(png_ptr, (void *)sk_stream, sk_read_fn);
    png_set_seek_fn(png_ptr, sk_seek_fn);
    /* where user_io_ptr is a structure you want available to the callbacks */
    /* If we have already read some of the signature */
    // png_set_sig_bytes(png_ptr, 0 /* sig_read */ );

    // hookup our peeker so we can see any user-chunks the caller may be interested in
    png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_ALWAYS, (png_byte*)"", 0);
    if (this->getPeeker()) {
        png_set_read_user_chunk_fn(png_ptr, (png_voidp)this->getPeeker(), sk_read_user_chunk);
    }

    /* The call to png_read_info() gives us all of the information from the
    * PNG file before the first IDAT (image data chunk). */
    png_read_info(png_ptr, info_ptr);
    png_uint_32 origWidth, origHeight;
    int bit_depth, color_type, interlace_type;
    png_get_IHDR(png_ptr, info_ptr, &origWidth, &origHeight, &bit_depth,
            &color_type, &interlace_type, int_p_NULL, int_p_NULL);

    /* tell libpng to strip 16 bit/color files down to 8 bits/color */
    if (bit_depth == 16) {
        png_set_strip_16(png_ptr);
    }
    /* Extract multiple pixels with bit depths of 1, 2, and 4 from a single
     * byte into separate bytes (useful for paletted and grayscale images). */
    if (bit_depth < 8) {
        png_set_packing(png_ptr);
    }
    /* 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_ptr);
    }

    /* Make a grayscale image into RGB. */
    if (color_type == PNG_COLOR_TYPE_GRAY ||
        color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
        png_set_gray_to_rgb(png_ptr);
    }
    return true;
}
コード例 #19
0
ファイル: png-module.c プロジェクト: Distrotech/slang
/* For little endian systems, ARGB is equivalent to the int32 BGRA.
 * So, to read the image as RGB
 */
static SLang_Array_Type *read_image_internal (char *file, int flip, int *color_typep)
{
   Png_Type *p;
   png_uint_32 width, height, rowbytes;
   png_struct *png;
   png_info *info;
   int bit_depth;
   int interlace_type;
   int color_type;
   unsigned int sizeof_type;
   SLindex_Type dims[2];
   SLtype data_type;
   png_byte **image_pointers = NULL;
   png_byte *data = NULL;
   SLang_Array_Type *at;
   void (*fixup_array_fun) (SLang_Array_Type *);

   if (NULL == (p = open_png_file (file)))
     return NULL;

   png = p->png;
   if (setjmp (png_jmpbuf (png)))
     {
	free_png_type (p);
	if (data != NULL) SLfree ((char *) data);
	free_image_pointers (image_pointers);
	SLang_verror (SL_Read_Error, "Error encountered during I/O to %s", file);
	return NULL;
     }

   png_init_io (png, p->fp);
   png_set_sig_bytes (png, 8);
   info = p->info;
   png_read_info(png, info);

   width = png_get_image_width (png, info);
   height = png_get_image_height (png, info);
   interlace_type = png_get_interlace_type (png, info);
   bit_depth = png_get_bit_depth (png, info);

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

   switch (png_get_color_type (png, info))
     {
      case PNG_COLOR_TYPE_GRAY:
#if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10209)
	if (bit_depth < 8) png_set_expand_gray_1_2_4_to_8 (png);
#else				       /* deprecated */
	if (bit_depth < 8) png_set_gray_1_2_4_to_8 (png);
#endif
	break;
      case PNG_COLOR_TYPE_GRAY_ALPHA:
	/* png_set_gray_to_rgb (png); */
	break;

      case PNG_COLOR_TYPE_PALETTE:
	png_set_palette_to_rgb (png);
	break;
     }

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

   png_read_update_info (png, info);

   color_type = png_get_color_type (png, info);
   switch (color_type)
     {
      case PNG_COLOR_TYPE_RGBA:
	sizeof_type = 4;
	fixup_array_fun = fixup_array_rgba;
	data_type = SLang_get_int_type (32);
	break;

      case PNG_COLOR_TYPE_RGB:
	sizeof_type = 4;
	fixup_array_fun = fixup_array_rgb;
	data_type = SLang_get_int_type (32);
	break;

      case PNG_COLOR_TYPE_GRAY_ALPHA:
	sizeof_type = 2;
	fixup_array_fun = fixup_array_ga;
	data_type = SLang_get_int_type (16);
	break;

      case PNG_COLOR_TYPE_GRAY:
	sizeof_type = 1;
	fixup_array_fun = NULL;
	data_type = SLANG_UCHAR_TYPE;
	break;

      default:
	SLang_verror (SL_Read_Error, "Unsupported PNG color-type");
	free_png_type (p);
	return NULL;
     }
   *color_typep = color_type;

   /* Use the high-level interface */
   rowbytes = png_get_rowbytes (png, info);
   if (rowbytes > width * sizeof_type)
     {
	SLang_verror (SL_INTERNAL_ERROR, "Unexpected value returned from png_get_rowbytes");
	free_png_type (p);
	return NULL;
     }

   if (NULL == (data = (png_byte *) SLmalloc (height * width * sizeof_type)))
     {
	free_png_type (p);
	return NULL;
     }

   if (NULL == (image_pointers = allocate_image_pointers (height, data, width * sizeof_type, flip)))
     {
	SLfree ((char *) data);
	free_png_type (p);
	return NULL;
     }
   png_read_image(png, image_pointers);

   dims[0] = height;
   dims[1] = width;

   if (NULL == (at = SLang_create_array (data_type, 0, (VOID_STAR) data, dims, 2)))
     {
	SLfree ((char *) data);
	free_image_pointers (image_pointers);
	free_png_type (p);
	return NULL;
     }
   free_png_type (p);
   free_image_pointers (image_pointers);
   if (fixup_array_fun != NULL)
     (*fixup_array_fun) (at);
   return at;
}
コード例 #20
0
static Bool
readPngData (png_struct	*png,
	     png_info	*info,
	     void	**data,
	     int	*width,
	     int	*height)
{
    png_uint_32	 png_width, png_height;
    int		 depth, color_type, interlace, i;
    unsigned int pixel_size;
    png_byte	 **row_pointers;
    char	 *d;

    png_read_info (png, info);

    png_get_IHDR (png, info,
		  &png_width, &png_height, &depth,
		  &color_type, &interlace, NULL, NULL);

    *width  = (int) png_width;
    *height = (int) png_height;

    /* 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 && depth < 8)
	png_set_gray_1_2_4_to_8 (png);

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

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

    if (depth < 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_bgr (png);
    png_set_filler (png, 0xff, PNG_FILLER_AFTER);

    png_set_read_user_transform_fn (png, premultiplyData);

    png_read_update_info (png, info);

    pixel_size = 4;
    d = (char *) malloc (png_width * png_height * pixel_size);
    if (!d)
	return FALSE;

    *data = d;

    row_pointers = (png_byte **) malloc (png_height * sizeof (char *));
    if (!row_pointers)
    {
	free (d);
	return FALSE;
    }

    for (i = 0; i < png_height; i++)
	row_pointers[i] = (png_byte *) (d + i * png_width * pixel_size);

    png_read_image (png, row_pointers);
    png_read_end (png, info);

    free (row_pointers);

    return TRUE;
}
コード例 #21
0
ファイル: example.c プロジェクト: carriercomm/legacy
/* Read a PNG file.  You may want to return an error code if the read
 * fails (depending upon the failure).  There are two "prototypes" given
 * here - one where we are given the filename, and we need to open the
 * file, and the other where we are given an open file (possibly with
 * some or all of the magic bytes read - see comments above).
 */
#ifdef open_file /* prototype 1 */
void read_png(char *file_name)  /* We need to open the file */
{
   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;
   FILE *fp;

   if ((fp = fopen(file_name, "rb")) == NULL)
      return (ERROR);
#else no_open_file /* prototype 2 */
void read_png(FILE *fp, unsigned int sig_read)  /* file is already open */
{
   png_structp png_ptr;
   png_infop info_ptr;
   png_uint_32 width, height;
   int bit_depth, color_type, interlace_type;
#endif no_open_file /* only use one prototype! */

   /* Create and initialize the png_struct with the desired error handler
    * functions.  If you want to use the default stderr and longjump method,
    * you can supply NULL for the last three parameters.  We also supply the
    * the compiler header file version, so that we know if the application
    * was compiled with a compatible version of the library.  REQUIRED
    */
   png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
      png_voidp user_error_ptr, user_error_fn, user_warning_fn);

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

   /* Allocate/initialize the memory for image information.  REQUIRED. */
   info_ptr = png_create_info_struct(png_ptr);
   if (info_ptr == NULL)
   {
      fclose(fp);
      png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
      return (ERROR);
   }

   /* 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_ptr)))
   {
      /* Free all of the memory associated with the png_ptr and info_ptr */
      png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
      fclose(fp);
      /* If we get here, we had a problem reading the file */
      return (ERROR);
   }

   /* One of the following I/O initialization methods is REQUIRED */
#ifdef streams /* PNG file I/O method 1 */
   /* Set up the input control if you are using standard C streams */
   png_init_io(png_ptr, fp);

#else no_streams /* PNG file I/O method 2 */
   /* If you are using replacement read functions, instead of calling
    * png_init_io() here you would call:
    */
   png_set_read_fn(png_ptr, (void *)user_io_ptr, user_read_fn);
   /* where user_io_ptr is a structure you want available to the callbacks */
#endif no_streams /* Use only one I/O method! */

   /* If we have already read some of the signature */
   png_set_sig_bytes(png_ptr, sig_read);

#ifdef hilevel
   /*
    * If you have enough memory to read in the entire image at once,
    * and you need to specify only transforms that can be controlled
    * with one of the PNG_TRANSFORM_* bits (this presently excludes
    * dithering, filling, setting background, and doing gamma
    * adjustment), then you can read the entire image (including
    * pixels) into the info structure with this call:
    */
   png_read_png(png_ptr, info_ptr, png_transforms, png_voidp_NULL);
#else
   /* OK, you're doing it the hard way, with the lower-level functions */

   /* 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_ptr, info_ptr);

   png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
       &interlace_type, int_p_NULL, int_p_NULL);

/* Set up the data transformations you want.  Note that these are all
 * optional.  Only call them if you want/need them.  Many of the
 * transformations only work on specific types of images, and many
 * are mutually exclusive.
 */

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

   /* Strip alpha bytes from the input data without combining with the
    * background (not recommended).
    */
   png_set_strip_alpha(png_ptr);

   /* Extract multiple pixels with bit depths of 1, 2, and 4 from a single
    * byte into separate bytes (useful for paletted and grayscale images).
    */
   png_set_packing(png_ptr);

   /* Change the order of packed pixels to least significant bit first
    * (not useful if you are using png_set_packing). */
   png_set_packswap(png_ptr);

   /* Expand paletted colors into true RGB triplets */
   if (color_type == PNG_COLOR_TYPE_PALETTE)
      png_set_palette_rgb(png_ptr);

   /* 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_ptr);

   /* 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_ptr, info_ptr, PNG_INFO_tRNS))
      png_set_tRNS_to_alpha(png_ptr);

   /* Set the background color to draw transparent and alpha images over.
    * It is possible to set the red, green, and blue components directly
    * for paletted images instead of supplying a palette index.  Note that
    * even if the PNG file supplies a background, you are not required to
    * use it - you should use the (solid) application background if it has one.
    */

   png_color_16 my_background, *image_background;

   if (png_get_bKGD(png_ptr, info_ptr, &image_background))
      png_set_background(png_ptr, image_background,
                         PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
   else
      png_set_background(png_ptr, &my_background,
                         PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);

   /* Some suggestions as to how to get a screen gamma value */

   /* Note that screen gamma is the display_exponent, which includes
    * the CRT_exponent and any correction for viewing conditions */
   if (/* We have a user-defined screen gamma value */)
   {
      screen_gamma = user-defined screen_gamma;
   }
   /* This is one way that applications share the same screen gamma value */
   else if ((gamma_str = getenv("SCREEN_GAMMA")) != NULL)
コード例 #22
0
ファイル: grfmt_png.cpp プロジェクト: 2693/opencv
bool  PngDecoder::readData( Mat& img )
{
    bool result = false;
    AutoBuffer<uchar*> _buffer(m_height);
    uchar** buffer = _buffer;
    int color = img.channels() > 1;
    uchar* data = img.data;
    int step = (int)img.step;

    if( m_png_ptr && m_info_ptr && m_end_info && m_width && m_height )
    {
        png_structp png_ptr = (png_structp)m_png_ptr;
        png_infop info_ptr = (png_infop)m_info_ptr;
        png_infop end_info = (png_infop)m_end_info;

        if( setjmp( png_jmpbuf ( png_ptr ) ) == 0 )
        {
            int y;

            if( img.depth() == CV_8U && m_bit_depth == 16 )
                png_set_strip_16( png_ptr );
            else if( !isBigEndian() )
                png_set_swap( png_ptr );

            if(img.channels() < 4)
            {
                /* observation: png_read_image() writes 400 bytes beyond
                 * end of data when reading a 400x118 color png
                 * "mpplus_sand.png".  OpenCV crashes even with demo
                 * programs.  Looking at the loaded image I'd say we get 4
                 * bytes per pixel instead of 3 bytes per pixel.  Test
                 * indicate that it is a good idea to always ask for
                 * stripping alpha..  18.11.2004 Axel Walthelm
                 */
                 png_set_strip_alpha( png_ptr );
            }

            if( m_color_type == PNG_COLOR_TYPE_PALETTE )
                png_set_palette_to_rgb( png_ptr );

            if( m_color_type == PNG_COLOR_TYPE_GRAY && m_bit_depth < 8 )
#if (PNG_LIBPNG_VER_MAJOR*10000 + PNG_LIBPNG_VER_MINOR*100 + PNG_LIBPNG_VER_RELEASE >= 10209) || \
    (PNG_LIBPNG_VER_MAJOR == 1 && PNG_LIBPNG_VER_MINOR == 0 && PNG_LIBPNG_VER_RELEASE >= 18)
                png_set_expand_gray_1_2_4_to_8( png_ptr );
#else
                png_set_gray_1_2_4_to_8( png_ptr );
#endif

            if( CV_MAT_CN(m_type) > 1 && color )
                png_set_bgr( png_ptr ); // convert RGB to BGR
            else if( color )
                png_set_gray_to_rgb( png_ptr ); // Gray->RGB
            else
                png_set_rgb_to_gray( png_ptr, 1, 0.299, 0.587 ); // RGB->Gray

            png_read_update_info( png_ptr, info_ptr );

            for( y = 0; y < m_height; y++ )
                buffer[y] = data + y*step;

            png_read_image( png_ptr, buffer );
            png_read_end( png_ptr, end_info );

            result = true;
        }
    }

    close();
    return result;
}
コード例 #23
0
ファイル: pngdec.c プロジェクト: DCurrent/openbor
void png_set_expand_gray_1_2_4_to_8(png_structp png_ptr)
{
    png_set_gray_1_2_4_to_8(png_ptr);
}
コード例 #24
0
ファイル: gstpngdec.c プロジェクト: DylanZA/gst-plugins-good
static GstFlowReturn
gst_pngdec_caps_create_and_set (GstPngDec * pngdec)
{
  GstFlowReturn ret = GST_FLOW_OK;
  gint bpc = 0, color_type;
  png_uint_32 width, height;
  GstVideoFormat format = GST_VIDEO_FORMAT_UNKNOWN;

  g_return_val_if_fail (GST_IS_PNGDEC (pngdec), GST_FLOW_ERROR);

  /* Get bits per channel */
  bpc = png_get_bit_depth (pngdec->png, pngdec->info);

  /* Get Color type */
  color_type = png_get_color_type (pngdec->png, pngdec->info);

  /* Add alpha channel if 16-bit depth, but not for GRAY images */
  if ((bpc > 8) && (color_type != PNG_COLOR_TYPE_GRAY)) {
    png_set_add_alpha (pngdec->png, 0xffff, PNG_FILLER_BEFORE);
    png_set_swap (pngdec->png);
  }
#if 0
  /* We used to have this HACK to reverse the outgoing bytes, but the problem
   * that originally required the hack seems to have been in videoconvert's
   * RGBA descriptions. It doesn't seem needed now that's fixed, but might
   * still be needed on big-endian systems, I'm not sure. J.S. 6/7/2007 */
  if (color_type == PNG_COLOR_TYPE_RGB_ALPHA)
    png_set_bgr (pngdec->png);
#endif

  /* Gray scale with alpha channel converted to RGB */
  if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
    GST_LOG_OBJECT (pngdec,
        "converting grayscale png with alpha channel to RGB");
    png_set_gray_to_rgb (pngdec->png);
  }

  /* Gray scale converted to upscaled to 8 bits */
  if ((color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
      (color_type == PNG_COLOR_TYPE_GRAY)) {
    if (bpc < 8) {              /* Convert to 8 bits */
      GST_LOG_OBJECT (pngdec, "converting grayscale image to 8 bits");
#if PNG_LIBPNG_VER < 10400
      png_set_gray_1_2_4_to_8 (pngdec->png);
#else
      png_set_expand_gray_1_2_4_to_8 (pngdec->png);
#endif
    }
  }

  /* Palette converted to RGB */
  if (color_type == PNG_COLOR_TYPE_PALETTE) {
    GST_LOG_OBJECT (pngdec, "converting palette png to RGB");
    png_set_palette_to_rgb (pngdec->png);
  }

  png_set_interlace_handling (pngdec->png);

  /* Update the info structure */
  png_read_update_info (pngdec->png, pngdec->info);

  /* Get IHDR header again after transformation settings */
  png_get_IHDR (pngdec->png, pngdec->info, &width, &height,
      &bpc, &pngdec->color_type, NULL, NULL, NULL);

  GST_LOG_OBJECT (pngdec, "this is a %dx%d PNG image", (gint) width,
      (gint) height);

  switch (pngdec->color_type) {
    case PNG_COLOR_TYPE_RGB:
      GST_LOG_OBJECT (pngdec, "we have no alpha channel, depth is 24 bits");
      if (bpc == 8)
        format = GST_VIDEO_FORMAT_RGB;
      break;
    case PNG_COLOR_TYPE_RGB_ALPHA:
      GST_LOG_OBJECT (pngdec,
          "we have an alpha channel, depth is 32 or 64 bits");
      if (bpc == 8)
        format = GST_VIDEO_FORMAT_RGBA;
      else if (bpc == 16)
        format = GST_VIDEO_FORMAT_ARGB64;
      break;
    case PNG_COLOR_TYPE_GRAY:
      GST_LOG_OBJECT (pngdec,
          "We have an gray image, depth is 8 or 16 (be) bits");
      if (bpc == 8)
        format = GST_VIDEO_FORMAT_GRAY8;
      else if (bpc == 16)
        format = GST_VIDEO_FORMAT_GRAY16_BE;
      break;
    default:
      break;
  }

  if (format == GST_VIDEO_FORMAT_UNKNOWN) {
    GST_ELEMENT_ERROR (pngdec, STREAM, NOT_IMPLEMENTED, (NULL),
        ("pngdec does not support this color type"));
    ret = GST_FLOW_NOT_SUPPORTED;
    goto beach;
  }

  /* Check if output state changed */
  if (pngdec->output_state) {
    GstVideoInfo *info = &pngdec->output_state->info;

    if (width == GST_VIDEO_INFO_WIDTH (info) &&
        height == GST_VIDEO_INFO_HEIGHT (info) &&
        GST_VIDEO_INFO_FORMAT (info) == format) {
      goto beach;
    }
    gst_video_codec_state_unref (pngdec->output_state);
  }

  pngdec->output_state =
      gst_video_decoder_set_output_state (GST_VIDEO_DECODER (pngdec), format,
      width, height, pngdec->input_state);
  gst_video_decoder_negotiate (GST_VIDEO_DECODER (pngdec));
  GST_DEBUG ("Final %d %d", GST_VIDEO_INFO_WIDTH (&pngdec->output_state->info),
      GST_VIDEO_INFO_HEIGHT (&pngdec->output_state->info));

beach:
  return ret;
}
コード例 #25
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;
  }
コード例 #26
0
ファイル: png_io.c プロジェクト: mgregson/autopy
MMBitmapRef newMMBitmapFromPNG(const char *path, MMPNGReadError *err)
{
	FILE *fp;
	uint8_t header[8];
	png_struct *png_ptr = NULL;
	png_info *info_ptr = NULL;
	png_byte bit_depth, color_type;
	uint8_t *row, *bitmapData;
	uint8_t bytesPerPixel;
	png_uint_32 width, height, y;
	uint32_t bytewidth;

	if ((fp = fopen(path, "rb")) == NULL) {
		if (err != NULL) *err = kPNGAccessError;
		return NULL;
	}

	/* Initialize error code to generic value. */
	if (err != NULL) *err = kPNGGenericError;

	/* Validate the PNG. */
	if (fread(header, 1, sizeof header, fp) == 0) {
		if (err != NULL) *err = kPNGReadError;
		goto bail;
	} else if (!png_check_sig(header, sizeof(header))) {
		if (err != NULL) *err = kPNGInvalidHeaderError;
		goto bail;
	}

	png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
	if (png_ptr == NULL) goto bail;

	info_ptr = png_create_info_struct(png_ptr);
	if (info_ptr == NULL) goto bail;

	/* Set up error handling. */
	if (setjmp(png_jmpbuf(png_ptr))) {
		goto bail;
	}

	png_init_io(png_ptr, fp);

	/* Skip past the header. */
	png_set_sig_bytes(png_ptr, sizeof header);

	png_read_info(png_ptr, info_ptr);

	/* Convert different image types to common type to be read. */
	bit_depth = png_get_bit_depth(png_ptr, info_ptr);
	color_type = png_get_color_type(png_ptr, info_ptr);

	/* Convert color palettes to RGB. */
	if (color_type == PNG_COLOR_TYPE_PALETTE) {
		png_set_palette_to_rgb(png_ptr);
	}

	/* Convert PNG to bit depth of 8. */
	if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) {
#ifdef PNG_LIBPNG_VER_SONUM
#if PNG_LIBPNG_VER_SONUM  >= 14
		png_set_expand_gray_1_2_4_to_8(png_ptr);
#else
		png_set_gray_1_2_4_to_8(png_ptr);
#endif
#else
		png_set_gray_1_2_4_to_8(png_ptr);
#endif
	} else if (bit_depth == 16) {
		png_set_strip_16(png_ptr);
	}

	/* Convert transparency chunk to alpha channel. */
	if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))  {
		png_set_tRNS_to_alpha(png_ptr);
	}

	/* Convert gray images to RGB. */
	if (color_type == PNG_COLOR_TYPE_GRAY ||
	    color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
		png_set_gray_to_rgb(png_ptr);
	}

	/* Ignore alpha for now. */
	if (color_type & PNG_COLOR_MASK_ALPHA) {
		png_set_strip_alpha(png_ptr);
	}

	/* Get image attributes. */
	width = png_get_image_width(png_ptr, info_ptr);
	height = png_get_image_height(png_ptr, info_ptr);
	bytesPerPixel = 3; /* All images decompress to this size. */
	bytewidth = ADD_PADDING(width * bytesPerPixel); /* Align width. */

	/* Decompress the PNG row by row. */
	bitmapData = calloc(1, bytewidth * height);
	row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr));
	if (bitmapData == NULL || row == NULL) goto bail;
	for (y = 0; y < height; ++y) {
		png_uint_32 x;
		const uint32_t rowOffset = y * bytewidth;
		uint8_t *rowptr = row;
		png_read_row(png_ptr, (png_byte *)row, NULL);

		for (x = 0; x < width; ++x) {
			const uint32_t colOffset = x * bytesPerPixel;
			MMRGBColor *color = (MMRGBColor *)(bitmapData + rowOffset + colOffset);
			color->red = *rowptr++;
			color->green = *rowptr++;
			color->blue = *rowptr++;
		}
	}
	free(row);

	/* Finish reading. */
	png_read_end(png_ptr, NULL);
	png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
	fclose(fp);

	return createMMBitmap(bitmapData, width, height,
	                      bytewidth, bytesPerPixel * 8, bytesPerPixel);

bail:
	png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
	fclose(fp);
	return NULL;
}
コード例 #27
0
static struct gl_texture_t *ReadPNGFromFile (const char *filename) {

  struct gl_texture_t *texinfo;
  png_byte magic[8];
  png_structp png_ptr;
  png_infop info_ptr;
  int bit_depth, color_type;
  FILE *fp = NULL;
  png_bytep *row_pointers = NULL;
  png_uint_32 w, h;
  int i;

  /* Open image file */
  fp = fopen (filename, "rb");
  if (!fp)
    {
      fprintf (stderr, "error: couldn't open \"%s\"!\n", filename);
      return NULL;
    }

  /* Read magic number */
  fread (magic, 1, sizeof (magic), fp);

  /* Check for valid magic number */
  if (!png_check_sig (magic, sizeof (magic)))
    {
      fprintf (stderr, "error: \"%s\" is not a valid PNG image!\n",
	       filename);
      fclose (fp);
      return NULL;
    }

  /* Create a png read struct */
  png_ptr = png_create_read_struct
    (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
  if (!png_ptr)
    {
      fclose (fp);
      return NULL;
    }

  /* Create a png info struct */
  info_ptr = png_create_info_struct (png_ptr);
  if (!info_ptr)
    {
      fclose (fp);
      png_destroy_read_struct (&png_ptr, NULL, NULL);
      return NULL;
    }

  /* Create our OpenGL texture object */
  texinfo = (struct gl_texture_t *)
    malloc (sizeof (struct gl_texture_t));

  /* Initialize the setjmp for returning properly after a libpng
     error occured */
  if (setjmp (png_jmpbuf (png_ptr)))
    {
      fclose (fp);
      png_destroy_read_struct (&png_ptr, &info_ptr, NULL);

      if (row_pointers)
	free (row_pointers);

      if (texinfo)
	{
	  if (texinfo->texels)
	    free (texinfo->texels);

	  free (texinfo);
	}

      return NULL;
    }

  /* Setup libpng for using standard C fread() function
     with our FILE pointer */
  png_init_io (png_ptr, fp);

  /* Tell libpng that we have already read the magic number */
  png_set_sig_bytes (png_ptr, sizeof (magic));

  /* Read png info */
  png_read_info (png_ptr, info_ptr);

  /* Get some usefull information from header */
  bit_depth = png_get_bit_depth (png_ptr, info_ptr);
  color_type = png_get_color_type (png_ptr, info_ptr);

  /* Convert index color images to RGB images */
  if (color_type == PNG_COLOR_TYPE_PALETTE)
    png_set_palette_to_rgb (png_ptr);

  /* Convert 1-2-4 bits grayscale images to 8 bits
     grayscale. */
  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);

  if (bit_depth == 16)
    png_set_strip_16 (png_ptr);
  else if (bit_depth < 8)
    png_set_packing (png_ptr);

  /* Update info structure to apply transformations */
  png_read_update_info (png_ptr, info_ptr);

  /* Retrieve updated information */
  png_get_IHDR (png_ptr, info_ptr, &w, &h, &bit_depth,
		&color_type, NULL, NULL, NULL);
  texinfo->width = w;
  texinfo->height = h;

  /* Get image format and components per pixel */
  GetPNGtextureInfo (color_type, texinfo);

  /* We can now allocate memory for storing pixel data */
  texinfo->texels = (GLubyte *)malloc (sizeof (GLubyte) * texinfo->width
	       * texinfo->height * texinfo->internalFormat);

  /* Setup a pointer array.  Each one points at the begening of a row. */
  row_pointers = (png_bytep *)malloc (sizeof (png_bytep) * texinfo->height);

  for (i = 0; i < texinfo->height; ++i)
    {
      row_pointers[i] = (png_bytep)(texinfo->texels +
	((texinfo->height - (i + 1)) * texinfo->width * texinfo->internalFormat));
    }

  /* Read pixel data using row pointers */
  png_read_image (png_ptr, row_pointers);

  /* Finish decompression and release memory */
  png_read_end (png_ptr, NULL);
  png_destroy_read_struct (&png_ptr, &info_ptr, NULL);

  /* We don't need row pointers anymore */
  free (row_pointers);

  fclose (fp);
  return texinfo;
}
コード例 #28
0
ファイル: pngutil.c プロジェクト: Distrotech/gmerlin
gavl_video_frame_t * read_png(const char * filename,
                              gavl_video_format_t * format,
                              gavl_pixelformat_t pixelformat)
  {
  int i;
  unsigned char ** rows;
  
  gavl_video_converter_t * cnv;
  gavl_video_options_t * opt;
  gavl_video_format_t format_1;
  gavl_video_frame_t * frame, * frame_1;
    
  int bit_depth;
  int color_type;
  int has_alpha = 0;

  png_structp png_ptr;
  png_infop info_ptr;
  png_infop end_info;

  FILE * file;
  
  file = fopen(filename, "rb");

  if(!file)
    {
    fprintf(stderr, "Cannot open file %s\n", filename);
    return NULL;
    }
  
  png_ptr = png_create_read_struct
    (PNG_LIBPNG_VER_STRING, NULL,
     NULL, NULL);
  
  setjmp(png_jmpbuf(png_ptr));
  info_ptr = png_create_info_struct(png_ptr);


  end_info = png_create_info_struct(png_ptr);

  png_init_io(png_ptr, file);

  png_read_info(png_ptr, info_ptr);

  format->frame_width  = png_get_image_width(png_ptr, info_ptr);
  format->frame_height = png_get_image_height(png_ptr, info_ptr);

  format->image_width  = format->frame_width;
  format->image_height = format->frame_height;
  format->pixel_width = 1;
  format->pixel_height = 1;

  bit_depth  = png_get_bit_depth(png_ptr,  info_ptr);
  color_type = png_get_color_type(png_ptr, info_ptr);
  switch(color_type)
    {
    case PNG_COLOR_TYPE_GRAY:       /*  (bit depths 1, 2, 4, 8, 16) */
      if(bit_depth < 8)
#if GAVL_MAKE_BUILD(PNG_LIBPNG_VER_MAJOR, PNG_LIBPNG_VER_MINOR, PNG_LIBPNG_VER_RELEASE) < GAVL_MAKE_BUILD(1,2,9)
        png_set_gray_1_2_4_to_8(png_ptr);
#else
      png_set_expand_gray_1_2_4_to_8(png_ptr);
#endif
      if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
        {
        png_set_tRNS_to_alpha(png_ptr);
        has_alpha = 1;
        }
      png_set_gray_to_rgb(png_ptr);
      break;
    case PNG_COLOR_TYPE_GRAY_ALPHA: /*  (bit depths 8, 16) */
      if(bit_depth == 16)
        png_set_strip_16(png_ptr);
      png_set_gray_to_rgb(png_ptr);
      break;
    case PNG_COLOR_TYPE_PALETTE:    /*  (bit depths 1, 2, 4, 8) */
      png_set_palette_to_rgb(png_ptr);
      if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
        {
        png_set_tRNS_to_alpha(png_ptr);
        has_alpha = 1;
        }
      break;
    case PNG_COLOR_TYPE_RGB:        /*  (bit_depths 8, 16) */
      if(png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
        {
        png_set_tRNS_to_alpha(png_ptr);
        has_alpha = 1;
        }
      if(bit_depth == 16)
        png_set_strip_16(png_ptr);
      break;
    case PNG_COLOR_TYPE_RGB_ALPHA:  /*  (bit_depths 8, 16) */
      if(bit_depth == 16)
        png_set_strip_16(png_ptr);
      has_alpha = 1;
      break;
    }
  if(has_alpha)
    format->pixelformat = GAVL_RGBA_32;
  else
    format->pixelformat = GAVL_RGB_24;

  frame = gavl_video_frame_create(format);
  rows = malloc(format->frame_height * sizeof(*rows));
  for(i = 0; i < format->frame_height; i++)
    rows[i] = frame->planes[0] + i * frame->strides[0];

  png_read_image(png_ptr, rows);
  png_read_end(png_ptr, end_info);

  png_destroy_read_struct(&png_ptr, &info_ptr,
                          &end_info);
  fclose(file);
  free(rows);
  
  /* Check wether to set up the converter */

  if(format->pixelformat != pixelformat)
    {
    cnv = gavl_video_converter_create();
    opt = gavl_video_converter_get_options(cnv);
    gavl_video_options_set_alpha_mode(opt, GAVL_ALPHA_BLEND_COLOR);    

    gavl_video_format_copy(&format_1, format);
    format_1.pixelformat = pixelformat;
    frame_1 = gavl_video_frame_create(&format_1);
    
    gavl_video_converter_init(cnv, format, &format_1);
    
    gavl_video_convert(cnv, frame, frame_1);
    gavl_video_converter_destroy(cnv);
    format->pixelformat = pixelformat;
    }
  else
    frame_1 = NULL;

  if(frame_1)
    {
    gavl_video_frame_destroy(frame);
    return frame_1;
    }
  else
    return frame;
  }
コード例 #29
0
ファイル: texture.cpp プロジェクト: lightsgoout/interview
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;
}
コード例 #30
0
ファイル: image_png.c プロジェクト: colinbouvry/minuit
t_image *img_read_png(const char *filename)
{
	FILE *file ;
	png_byte magic[8];

	file = fopen(filename,"rb");
	if (!file)
	{
		printf("couldn't read %s\n",filename); return NULL;
	}

	size_t r = fread(magic,1,sizeof(magic),file);
	if(r != sizeof(magic)) printf("read error\n");

	if (!png_check_sig(magic,sizeof(magic)))
	{
		printf("no magic\n"); return NULL;
	}

	png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL);

	if (!png_ptr)
	{
		fclose(file);
		return NULL;
	}

	png_infop info_ptr  = png_create_info_struct(png_ptr);

	if(!info_ptr)
	{
		fclose(file);
		png_destroy_read_struct(&png_ptr,NULL,NULL);
		return NULL;
	}

	png_init_io(png_ptr,file);
	png_set_sig_bytes(png_ptr,sizeof(magic));
	png_read_info(png_ptr,info_ptr);

	int 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_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);
	if (bit_depth == 16)
		png_set_strip_16 (png_ptr);
	else if (bit_depth < 8)
		png_set_packing (png_ptr);

	png_read_update_info(png_ptr,info_ptr);

	png_uint_32 w, h;

	png_get_IHDR (png_ptr, info_ptr, &w, &h, &bit_depth, &color_type, NULL, NULL, NULL);


	char name_raw[_NAME_];
	image_get_filename( filename, name_raw);
	t_image *image = image_new( name_raw);

	image->width=w;
	image->height=h;
	image->file_type = IMG_PNG;
	image->data_type = IMG_BYTE;

	switch (color_type)
	{

		case PNG_COLOR_TYPE_GRAY:
			image->color_type = IMG_GRAYSCALE;
			image->alpha = 0;
			image->bpp = 1;
			break;

		case PNG_COLOR_TYPE_GRAY_ALPHA:
			image->color_type = IMG_GRAYSCALE;
			image->alpha = 1;
			image->bpp = 2;
			break;

		case PNG_COLOR_TYPE_RGB:
			image->color_type = IMG_RGB;
			image->alpha = 0;
			image->bpp = 3;
			break;

		case PNG_COLOR_TYPE_RGB_ALPHA:
			image->color_type = IMG_RGB;
			image->alpha = 1;
			image->bpp = 4;
			break;

		default:
			break;
	}


	image->vlst = vlst_make( "vlst", dt_uchar, image->width * image->height, image->bpp, NULL);

	png_bytep *row_pointers;

	row_pointers = (png_bytep *)mem_malloc (sizeof (png_bytep) * image->height);

	int i;
	for (i = 0; i < image->height; ++i)
	{
		row_pointers[i] = (png_bytep)(image->vlst->data +
		((image->height - (i + 1)) * image->width * image->bpp));
	}

	png_read_image (png_ptr, row_pointers);

	free (row_pointers);

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

	fclose (file);

	return image;
}