コード例 #1
0
ファイル: ImageIOpng.cpp プロジェクト: TPeterW/Ascii-Art
void ReadFilePNG(CByteImage& img, const char* filename)
{
    // open the PNG input file
    FILE *stream = fopen(filename, "rb");
    if (stream == 0)
        throw CError("ReadFilePNG: could not open %s", filename);

    // first check the eight byte PNG signature
    png_byte pbSig[8];
    fread(pbSig, 1, 8, stream);
	if (!png_check_sig(pbSig, 8)) {
        fclose(stream);
        throw CError("ReadFilePNG: invalid PNG signature");
	}

    // create the two png(-info) structures
    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL,
      (png_error_ptr)pngfile_error, (png_error_ptr)NULL);

	if (!png_ptr) {
        fclose(stream);
		throw CError("ReadFilePNG: error creating png structure");
	}

	info_ptr = png_create_info_struct(png_ptr);
	if (!info_ptr)
	{
		png_destroy_read_struct(&png_ptr, NULL, NULL);
        fclose(stream);
		throw CError("ReadFilePNG: error creating png structure");
	}

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

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

	// get width, height, bit-depth and color-type
	int width, height, bits, colorType, nBands;

	png_uint_32 pwidth, pheight;

	png_get_IHDR(png_ptr, info_ptr, 
		     &pwidth, &pheight,
		     //(png_uint_32 *)&width, (png_uint_32 *)&height,
		     &bits, &colorType, NULL, NULL, NULL);

	width = pwidth;
	height = pheight;

	nBands = (int)png_get_channels(png_ptr, info_ptr);

	if (DEBUG_ImageIOpng)
	fprintf(stderr, " w=%d, h=%d, %2d bits, %s, nB=%d",
		width, height, bits, 
		colorType == PNG_COLOR_TYPE_GRAY ? "gray" :
		colorType == PNG_COLOR_TYPE_PALETTE ? "plt " :
		colorType == PNG_COLOR_TYPE_RGB ? "rgb " :
		colorType == PNG_COLOR_TYPE_RGB_ALPHA ? "rgba" :
		colorType == PNG_COLOR_TYPE_GRAY_ALPHA ? "gr-a" : "??? ",
		nBands);


	// get rid of lower-order byte in 16-bit images
	// TODO: could allow this and read in IntImage in this case...
	if (bits == 16)
		png_set_strip_16(png_ptr);

	// change palette color into RGB
	if (colorType == PNG_COLOR_TYPE_PALETTE)
		png_set_expand(png_ptr);

	// want at least 8 bits
	if (bits < 8)
		png_set_expand(png_ptr);

	// if there is a transparent palette entry, create alpha channel
	if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
		png_set_expand(png_ptr);

	// make gray images with alpha channel into RGBA -- TODO: or just ignore alpha?
	if (colorType == PNG_COLOR_TYPE_GRAY_ALPHA)
		// colorType == PNG_COLOR_TYPE_GRAY       // but leave gray images alone
		png_set_gray_to_rgb(png_ptr);

	// set the background color to draw transparent and alpha images over.
	// only needed for gray images with alpha 
	if (colorType == PNG_COLOR_TYPE_GRAY_ALPHA ||
		colorType == PNG_COLOR_TYPE_GRAY) {
		png_color_16 *pBackground;
		if (png_get_bKGD(png_ptr, info_ptr, &pBackground))
			png_set_background(png_ptr, pBackground, PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
		}

	// if required set gamma conversion
	// this seems to cause problems, so let's just leave gamma alone.
	//double gamma;
	//if (png_get_gAMA(png_ptr, info_ptr, &gamma)) {
	// //fprintf(stderr, "\n reading gamma %lf\n", gamma);
	//png_set_gamma(png_ptr, 1.0, gamma);
	//}

	// we need colors in BGR order, not RGB
	png_set_bgr(png_ptr);

	// always convert 3-band to 4-band images (add alpha):
	if (colorType == PNG_COLOR_TYPE_RGB)
		png_set_add_alpha(png_ptr, 255, PNG_FILLER_AFTER);

	// after the transformations have been registered update info_ptr data
	png_read_update_info(png_ptr, info_ptr);

	// get again width, height and the new bit-depth and color-type

	png_get_IHDR(png_ptr, info_ptr, 
		     &pwidth, &pheight,
		     //(png_uint_32 *)&width, (png_uint_32 *)&height,
		     &bits, &colorType, NULL, NULL, NULL);
	
	width = pwidth;
	height = pheight;

	nBands = (int)png_get_channels(png_ptr, info_ptr);

	if (DEBUG_ImageIOpng)
	fprintf(stderr, "  -> w=%d, h=%d, %2d bits, %s, nB=%d\n",
		width, height, bits,
		colorType == PNG_COLOR_TYPE_GRAY ? "gray" :
		colorType == PNG_COLOR_TYPE_PALETTE ? "plt " :
		colorType == PNG_COLOR_TYPE_RGB ? "rgb " :
		colorType == PNG_COLOR_TYPE_RGB_ALPHA ? "rgba" :
		colorType == PNG_COLOR_TYPE_GRAY_ALPHA ? "gr-a" : "??? ",
		nBands);
	

	if (! (nBands==1 || nBands==3 || nBands==4)) {
        fclose(stream);
		throw CError("ReadFilePNG: Can't handle nBands=%d", nBands);
	}

	// Set the image shape
	CShape sh(width, height, nBands);

	// Allocate the image if necessary
	img.ReAllocate(sh);

	//  allocate a vector of row pointers
	std::vector<uchar *> rowPtrs;
	rowPtrs.resize(height);
	for (int y = 0; y<height; y++)
		rowPtrs[y] = &img.Pixel(0, y, 0);

	// read the whole image
	png_read_image(png_ptr, &rowPtrs[0]);

 	// read the additional chunks in the PNG file (not really needed)
	png_read_end(png_ptr, NULL);

	png_destroy_read_struct(&png_ptr, &info_ptr, NULL);

	fclose(stream);
}
コード例 #2
0
ファイル: dr_rdpng.c プロジェクト: nathansamson/simutrans
static void read_png(unsigned char** block, unsigned* width, unsigned* height, FILE* file, const int base_img_size)
{
	png_structp png_ptr;
	png_infop   info_ptr;
	png_bytep* row_pointers;
	unsigned row, x, y;
	int rowbytes;
	char* dst;

	//png_uint_32 is 64 bit on some architectures!
	png_uint_32 widthpu32,heightpu32;

	png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL);
	if (png_ptr == NULL) {
		printf("read_png: Could not create read struct.\n");
		exit(1);
	}

	info_ptr = png_create_info_struct(png_ptr);
	if (info_ptr == NULL) {
		printf("read_png: Could not create info struct.\n");
		png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
		exit(1);
	}


	if (setjmp(png_ptr->jmpbuf)) {
		printf("read_png: fatal error.\n");
		png_destroy_read_struct(&png_ptr, &info_ptr, (png_info**)0);
		/* free pointers before returning, if necessary */
		free(png_ptr);
		free(info_ptr);
		exit(1);
	}

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


	/* 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,
		&widthpu32, &heightpu32, &bit_depth, &color_type,
		&interlace_type, NULL, NULL
	);
	*width = widthpu32;
	*height = heightpu32;

	if (*height % base_img_size != 0 || *width % base_img_size != 0) {
		printf("read_png: Invalid image size.\n");
		exit(1);
	}
	// printf("read_png: width=%d, height=%d, bit_depth=%d\n", width, height, bit_depth);
	// printf("read_png: color_type=%d, interlace_type=%d\n", color_type, interlace_type);


	/* 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 */
	png_set_expand(png_ptr);


	png_start_read_image(png_ptr);

	/* The easiest way to read the image: */

	rowbytes = png_get_rowbytes(png_ptr, info_ptr) * 3;
	row_pointers = malloc(*height * sizeof(*row_pointers));

	row_pointers[0] = malloc(rowbytes * *height * 2);

	for (row = 1; row < *height; row++) {
		row_pointers[row] = row_pointers[row - 1] + rowbytes * 2;
	}
	/* Read the entire image in one go */
	png_read_image(png_ptr, row_pointers);

	// we use fixed height here because block is of limited, fixed size
	// not fixed any more

	*block = realloc(*block, *height * *width * 6);

	// *block = malloc(*height * *width * 6);

	dst = *block;
	for (y = 0; y < *height; y++) {
		for (x = 0; x < *width * 3; x++) {
			*dst++ = row_pointers[y][x];
			// *dst++ = 0;
		}
	}

	free(row_pointers[0]);
	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);
}
コード例 #3
0
void LoadPNG( const char *name, byte **pic, int *width, int *height,
	      int *numLayers, int *numMips, int *bits, byte alphaByte )
{
	int          bit_depth;
	int          color_type;
	png_uint_32  w;
	png_uint_32  h;
	unsigned int row;
	png_infop    info;
	png_structp  png;
	png_bytep    *row_pointers;
	byte         *data;
	byte         *out;

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

	if ( !data )
	{
		return;
	}

	png = png_create_read_struct( PNG_LIBPNG_VER_STRING, ( png_voidp ) nullptr, png_user_error_fn, png_user_warning_fn );

	if ( !png )
	{
		ri.Printf( PRINT_WARNING, "LoadPNG: png_create_write_struct() failed for (%s)\n", name );
		ri.FS_FreeFile( data );
		return;
	}

	// allocate/initialize the memory for image information.  REQUIRED
	info = png_create_info_struct( png );

	if ( !info )
	{
		ri.Printf( PRINT_WARNING, "LoadPNG: png_create_info_struct() failed for (%s)\n", name );
		ri.FS_FreeFile( data );
		png_destroy_read_struct( &png, ( png_infopp ) nullptr, ( png_infopp ) nullptr );
		return;
	}

	/*
	 * Set error handling if you are using the setjmp/longjmp method (this is
	 * the common method of doing things with libpng).  REQUIRED unless you
	 * set up your own error handlers in the png_create_read_struct() earlier.
	 */
	if ( setjmp( png_jmpbuf( png ) ) )
	{
		// if we get here, we had a problem reading the file
		ri.Printf( PRINT_WARNING, "LoadPNG: first exception handler called for (%s)\n", name );
		ri.FS_FreeFile( data );
		png_destroy_read_struct( &png, ( png_infopp ) & info, ( png_infopp ) nullptr );
		return;
	}

	png_set_read_fn( png, data, png_read_data );

	png_set_sig_bytes( png, 0 );

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

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

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

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

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

	// expand grayscale images to the full 8 bits from 1, 2, or 4 bits/pixel

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

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

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

	png_set_interlace_handling( png );

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

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

	row_pointers = ( png_bytep * ) ri.Hunk_AllocateTempMemory( sizeof( png_bytep ) * h );

	// set a new exception handler
	if ( setjmp( png_jmpbuf( png ) ) )
	{
		ri.Printf( PRINT_WARNING, "LoadPNG: second exception handler called for (%s)\n", name );
		ri.Hunk_FreeTempMemory( row_pointers );
		ri.FS_FreeFile( data );
		png_destroy_read_struct( &png, ( png_infopp ) & info, ( png_infopp ) nullptr );
		return;
	}

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

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

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

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

	ri.Hunk_FreeTempMemory( row_pointers );
	ri.FS_FreeFile( data );
}
コード例 #4
0
ファイル: imagpng.cpp プロジェクト: Jiang0Ke/wxWidgets
bool
wxPNGHandler::LoadFile(wxImage *image,
                       wxInputStream& stream,
                       bool verbose,
                       int WXUNUSED(index))
{
    // VZ: as this function uses setjmp() the only fool-proof error handling
    //     method is to use goto (setjmp is not really C++ dtors friendly...)

    unsigned char **lines = NULL;
    png_infop info_ptr = (png_infop) NULL;
    wxPNGInfoStruct wxinfo;

    png_uint_32 i, width, height = 0;
    int bit_depth, color_type, interlace_type;

    wxinfo.verbose = verbose;
    wxinfo.stream.in = &stream;

    image->Destroy();

    png_structp png_ptr = png_create_read_struct
                          (
                            PNG_LIBPNG_VER_STRING,
                            NULL,
                            wx_PNG_error,
                            wx_PNG_warning
                          );
    if (!png_ptr)
        goto error;

    // NB: please see the comment near wxPNGInfoStruct declaration for
    //     explanation why this line is mandatory
    png_set_read_fn( png_ptr, &wxinfo, wx_PNG_stream_reader);

    info_ptr = png_create_info_struct( png_ptr );
    if (!info_ptr)
        goto error;

    if (setjmp(wxinfo.jmpbuf))
        goto error;

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

    if (color_type == PNG_COLOR_TYPE_PALETTE)
        png_set_expand( png_ptr );

    // Fix for Bug [ 439207 ] Monochrome PNG images come up black
    if (bit_depth < 8)
        png_set_expand( png_ptr );

    png_set_strip_16( png_ptr );
    png_set_packing( png_ptr );
    if (png_get_valid( png_ptr, info_ptr, PNG_INFO_tRNS))
        png_set_expand( png_ptr );
    png_set_filler( png_ptr, 0xff, PNG_FILLER_AFTER );

    image->Create((int)width, (int)height, (bool) false /* no need to init pixels */);

    if (!image->IsOk())
        goto error;

    // initialize all line pointers to NULL to ensure that they can be safely
    // free()d if an error occurs before all of them could be allocated
    lines = (unsigned char **)calloc(height, sizeof(unsigned char *));
    if ( !lines )
        goto error;

    for (i = 0; i < height; i++)
    {
        if ((lines[i] = (unsigned char *)malloc( (size_t)(width * 4))) == NULL)
            goto error;
    }

    png_read_image( png_ptr, lines );
    png_read_end( png_ptr, info_ptr );

#if wxUSE_PALETTE
    if (color_type == PNG_COLOR_TYPE_PALETTE)
    {
        png_colorp palette = NULL;
        int numPalette = 0;

        (void) png_get_PLTE(png_ptr, info_ptr, &palette, &numPalette);

        unsigned char* r = new unsigned char[numPalette];
        unsigned char* g = new unsigned char[numPalette];
        unsigned char* b = new unsigned char[numPalette];

        for (int j = 0; j < numPalette; j++)
        {
            r[j] = palette[j].red;
            g[j] = palette[j].green;
            b[j] = palette[j].blue;
        }

        image->SetPalette(wxPalette(numPalette, r, g, b));
        delete[] r;
        delete[] g;
        delete[] b;
    }
#endif // wxUSE_PALETTE


    // set the image resolution if it's available
    png_uint_32 resX, resY;
    int unitType;
    if (png_get_pHYs(png_ptr, info_ptr, &resX, &resY, &unitType)
        == PNG_INFO_pHYs)
    {
        wxImageResolution res = wxIMAGE_RESOLUTION_CM;

        switch (unitType)
        {
            default:
                wxLogWarning(_("Unknown PNG resolution unit %d"), unitType);
                wxFALLTHROUGH;

            case PNG_RESOLUTION_UNKNOWN:
                image->SetOption(wxIMAGE_OPTION_RESOLUTIONX, resX);
                image->SetOption(wxIMAGE_OPTION_RESOLUTIONY, resY);

                res = wxIMAGE_RESOLUTION_NONE;
                break;

            case PNG_RESOLUTION_METER:
                /*
                Convert meters to centimeters.
                Use a string to not lose precision (converting to cm and then
                to inch would result in integer rounding error).
                If an app wants an int, GetOptionInt will convert and round
                down for them.
                */
                image->SetOption(wxIMAGE_OPTION_RESOLUTIONX,
                    wxString::FromCDouble((double) resX / 100.0, 2));
                image->SetOption(wxIMAGE_OPTION_RESOLUTIONY,
                    wxString::FromCDouble((double) resY / 100.0, 2));
                break;
        }

        image->SetOption(wxIMAGE_OPTION_RESOLUTIONUNIT, res);
    }


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

    // loaded successfully, now init wxImage with this data
    CopyDataFromPNG(image, lines, width, height, color_type);

    for ( i = 0; i < height; i++ )
        free( lines[i] );
    free( lines );

    return true;

error:
    if (verbose)
    {
       wxLogError(_("Couldn't load a PNG image - file is corrupted or not enough memory."));
    }

    if ( image->IsOk() )
    {
        image->Destroy();
    }

    if ( lines )
    {
        for ( unsigned int n = 0; n < height; n++ )
            free( lines[n] );

        free( lines );
    }

    if ( png_ptr )
    {
        if ( info_ptr )
        {
            png_destroy_read_struct( &png_ptr, &info_ptr, (png_infopp) NULL );
            free(info_ptr);
        }
        else
            png_destroy_read_struct( &png_ptr, (png_infopp) NULL, (png_infopp) NULL );
    }
    return false;
}
コード例 #5
0
ファイル: pngread.c プロジェクト: bubbg/lambdanative
void PNGAPI
png_read_png(png_structp png_ptr, png_infop info_ptr,
                           int transforms,
                           voidp params)
{
   int row;

#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
   /* invert the alpha channel from opacity to transparency
    */
   if (transforms & PNG_TRANSFORM_INVERT_ALPHA)
       png_set_invert_alpha(png_ptr);
#endif

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

#ifdef PNG_FREE_ME_SUPPORTED
   png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
#endif
   if(info_ptr->row_pointers == NULL)
   {
      info_ptr->row_pointers = (png_bytepp)png_malloc(png_ptr,
         info_ptr->height * png_sizeof(png_bytep));
#ifdef PNG_FREE_ME_SUPPORTED
      info_ptr->free_me |= PNG_FREE_ROWS;
#endif
      for (row = 0; row < (int)info_ptr->height; row++)
      {
         info_ptr->row_pointers[row] = (png_bytep)png_malloc(png_ptr,
            png_get_rowbytes(png_ptr, info_ptr));
      }
   }

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

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

   if(transforms == 0 || params == NULL)
      /* quiet compiler warnings */ return;

}
コード例 #6
0
ファイル: mpng.c プロジェクト: mcgrew/lxvt
long
PngReadFileToPixmap (Display* display, Window window, GC gc, char* filename, Pixmap* pixmap, long* w, long* h)
{
    int red_mask, green_mask, blue_mask;
    int red_shift, green_shift, blue_shift;
    int start_shift, msb_flag;
    unsigned int start_mask, udat;
    XWindowAttributes win_attr;
    FILE* ifile;
  long display_depth;
      png_byte            sig[8];
  png_infop info_ptr;
  png_structp png_ptr;
      png_uint_32 png_width;
    png_uint_32 png_height;
    int png_depth;
    int png_color_type;
png_uint_32 png_row_bytes;
  png_uint_32 png_channels;
    long rwidth;
    long rheight;
    long components;
    unsigned char* buf;
    png_byte** png_row_ptrs;
    long vwidth;
    long vheight;
    long stretched;
    XImage* image;
    Visual* visual;
    Pixmap pix;
    int i;
    char* data1;
    unsigned char r,g,b;
    long ptr = 0;
    long ptr2 = 0;
    long j;

    red_mask = green_mask = blue_mask = 0;
    red_shift = green_shift = blue_shift = 0;

    ifile = fopen(filename,"r");
    if (ifile == NULL){
      return -1;
    }
    display_depth = XDefaultDepth(display,XDefaultScreen(display));

    fread(sig, 1, 8, ifile);
    if (png_sig_cmp(sig, 0, 8)){
      fclose(ifile);
      return -1;
    }
    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){
      fclose(ifile);
      return -1;
    } 
    info_ptr = png_create_info_struct(png_ptr);
    if (info_ptr == NULL){
      png_destroy_read_struct(&png_ptr, NULL, NULL);
      fclose(ifile);
      return -1;
    }

    png_init_io(png_ptr, ifile);
    png_set_sig_bytes(png_ptr, 8);
    png_read_info(png_ptr, info_ptr);
    png_get_IHDR(png_ptr, info_ptr, &png_width, &png_height, &png_depth,
            &png_color_type, NULL, NULL, NULL);
    if (png_depth == 16){
      png_set_strip_16(png_ptr);
    }
    png_row_bytes = png_get_rowbytes(png_ptr, info_ptr);
    png_channels = png_get_channels(png_ptr, info_ptr);

    if (png_depth < 8){
      if (png_color_type == PNG_COLOR_TYPE_GRAY ){
        png_set_expand_gray_1_2_4_to_8(png_ptr);
        png_row_bytes = png_width;
      }else{
        png_set_expand(png_ptr);
        png_row_bytes = png_width;
        png_row_bytes = png_width * 3;
        png_channels = 3;
      }
    }
    if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)){
      png_set_expand(png_ptr);
      png_row_bytes = png_width;
    }
    if (png_color_type == PNG_COLOR_TYPE_GRAY ||
        png_color_type == PNG_COLOR_TYPE_GRAY_ALPHA){
      png_set_gray_to_rgb(png_ptr);
      png_row_bytes = png_width;
    }

    if (png_color_type == PNG_COLOR_TYPE_PALETTE){
      png_set_palette_to_rgb(png_ptr);
      png_row_bytes = png_width * 3;
      png_channels = 3;
    }

    rwidth = png_width;
    rheight = png_height;
    components = png_channels;

    /* possible integer overflow? */
    assert ((int) png_row_bytes > 0);
    assert ((int) png_height > 0);
    assert (((int)png_row_bytes) * ((int)png_height) * sizeof(png_byte) > 0);
    buf = rxvt_malloc(png_row_bytes * png_height * sizeof(png_byte));
    if (buf == NULL){
      rxvt_msg (DBG_ERROR, DBG_IMAGES, "png read error: out of memory..\n");
      png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
      fclose(ifile);
      return -1;
    }
    /* possible integer overflow? */
    assert ((int) png_height > 0);
    assert (sizeof(png_bytep) * ((int)png_height) > 0);
    png_row_ptrs = rxvt_malloc (sizeof(png_bytep)*png_height);
    if (png_row_ptrs == NULL){
      rxvt_msg (DBG_ERROR, DBG_IMAGES, "png read error: out of memory..\n");
      png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
      fclose(ifile);
      return -1;
    }

    for(i = 0; i < (int)png_height; i++){
      png_row_ptrs[i] = (png_byte*)(buf + i * png_row_bytes);
    }
    png_read_image(png_ptr, png_row_ptrs);
    png_read_end(png_ptr,NULL);
    rxvt_free(png_row_ptrs);

    vwidth = *w;
    vheight = *h;
    stretched =0;
    if (*w == 0 || *h == 0){
      *w = rwidth;
      *h = rheight;
    }else{
      if ((long)((double)rwidth * vheight/vwidth) < rheight){
        *w = (long)((double)vheight * rwidth/rheight);
      }else{
        *h = (long)((double)vwidth * rheight/rwidth);
      }
      stretched = 1;
    }
    vwidth = *w;
    vheight = *h;



    image = 0;
    visual = XDefaultVisual(display,XDefaultScreen(display));
    if (display_depth >16){
      image = XCreateImage(display,visual, display_depth,
                           ZPixmap,0,0,vwidth,vheight,32,0);
    }else
    if (display_depth >8){
      image = XCreateImage(display,visual, display_depth,
                           ZPixmap,0,0,vwidth,vheight,16,0);
    }else{
      image = XCreateImage(display,visual, display_depth,
                           ZPixmap,0,0,vwidth,vheight,8,0);
    }

    msb_flag = (ImageByteOrder(display) == MSBFirst)?1:0;

    if (XGetWindowAttributes(display,
                     RootWindow(display, DefaultScreen(display)),
                     &win_attr) == 0) {
        fclose(ifile);
                 return -1;
    }

    if ((win_attr.depth == 24) || (win_attr.depth == 16)) {
      unsigned int n;
      if (win_attr.depth == 24) {
        start_shift = 24;
        start_mask = 0x80000000;
      }else{
        start_shift = 8;
        start_mask = 0x8000;
      }
      red_mask = win_attr.visual->red_mask;
      red_shift = start_shift;
      n = start_mask;
      while (!(n & red_mask)) {
        n >>= 1;
        red_shift--;
      }
      green_mask = win_attr.visual->green_mask;
      green_shift = start_shift;
      n = start_mask;
      while (!(n & green_mask)) {
        n >>= 1;
        green_shift--;
      }
      blue_mask = win_attr.visual->blue_mask;
      blue_shift = start_shift;
      n = start_mask;
      while (!(n & blue_mask)) {
        n >>= 1;
        blue_shift--;
      }
    }
コード例 #7
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;
}
コード例 #8
0
ファイル: _png.cpp プロジェクト: wrgiannjr/matplotlib
PyObject*
_png_module::_read_png(const Py::Object& py_fileobj, const bool float_result)
{
    png_byte header[8];   // 8 is the maximum size that can be checked
    FILE* fp = NULL;
    bool close_file = false;

#if PY3K
    int fd = PyObject_AsFileDescriptor(py_fileobj.ptr());
    PyErr_Clear();
#endif

    if (py_fileobj.isString())
    {
        std::string fileName = Py::String(py_fileobj);
        const char *file_name = fileName.c_str();
        if ((fp = fopen(file_name, "rb")) == NULL)
        {
            throw Py::RuntimeError(
                Printf("Could not open file %s for reading", file_name).str());
        }
        close_file = true;
    }
#if PY3K
    else if (fd != -1) {
        fp = fdopen(fd, "r");
    }
#else
    else if (PyFile_CheckExact(py_fileobj.ptr()))
    {
        fp = PyFile_AsFile(py_fileobj.ptr());
    }
#endif
    else
    {
        PyObject* read_method = PyObject_GetAttrString(py_fileobj.ptr(), "read");
        if (!(read_method && PyCallable_Check(read_method)))
        {
            Py_XDECREF(read_method);
            throw Py::TypeError("Object does not appear to be a 8-bit string path or a Python file-like object");
        }
        Py_XDECREF(read_method);
    }

    if (fp)
    {
        if (fread(header, 1, 8, fp) != 8)
        {
            throw Py::RuntimeError(
                "_image_module::readpng: error reading PNG header");
        }
    }
    else
    {
        _read_png_data(py_fileobj.ptr(), header, 8);
    }
    if (png_sig_cmp(header, 0, 8))
    {
        throw Py::RuntimeError(
            "_image_module::readpng: file not recognized as a PNG file");
    }

    /* initialize stuff */
    png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);

    if (!png_ptr)
    {
        throw Py::RuntimeError(
            "_image_module::readpng:  png_create_read_struct failed");
    }

    png_infop info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr)
    {
        throw Py::RuntimeError(
            "_image_module::readpng:  png_create_info_struct failed");
    }

    if (setjmp(png_jmpbuf(png_ptr)))
    {
        throw Py::RuntimeError(
            "_image_module::readpng:  error during init_io");
    }

    if (fp)
    {
        png_init_io(png_ptr, fp);
    }
    else
    {
        png_set_read_fn(png_ptr, (void*)py_fileobj.ptr(), &read_png_data);
    }
    png_set_sig_bytes(png_ptr, 8);
    png_read_info(png_ptr, info_ptr);

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

    int bit_depth = png_get_bit_depth(png_ptr, info_ptr);

    // Unpack 1, 2, and 4-bit images
    if (bit_depth < 8)
        png_set_packing(png_ptr);

    // If sig bits are set, shift data
    png_color_8p sig_bit;
    if ((png_get_color_type(png_ptr, info_ptr) != PNG_COLOR_TYPE_PALETTE) &&
        png_get_sBIT(png_ptr, info_ptr, &sig_bit))
    {
        png_set_shift(png_ptr, sig_bit);
    }

    // Convert big endian to little
    if (bit_depth == 16)
    {
        png_set_swap(png_ptr);
    }

    // Convert palletes to full RGB
    if (png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_PALETTE)
    {
        png_set_palette_to_rgb(png_ptr);
    }

    // If there's an alpha channel convert gray to RGB
    if (png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_GRAY_ALPHA)
    {
        png_set_gray_to_rgb(png_ptr);
    }

    png_set_interlace_handling(png_ptr);
    png_read_update_info(png_ptr, info_ptr);

    /* read file */
    if (setjmp(png_jmpbuf(png_ptr)))
    {
        throw Py::RuntimeError(
            "_image_module::readpng: error during read_image");
    }

    png_bytep *row_pointers = new png_bytep[height];
    png_uint_32 row;

    for (row = 0; row < height; row++)
    {
        row_pointers[row] = new png_byte[png_get_rowbytes(png_ptr,info_ptr)];
    }

    png_read_image(png_ptr, row_pointers);

    npy_intp dimensions[3];
    dimensions[0] = height;  //numrows
    dimensions[1] = width;   //numcols
    if (png_get_color_type(png_ptr, info_ptr) & PNG_COLOR_MASK_ALPHA)
    {
        dimensions[2] = 4;     //RGBA images
    }
    else if (png_get_color_type(png_ptr, info_ptr) & PNG_COLOR_MASK_COLOR)
    {
        dimensions[2] = 3;     //RGB images
    }
    else
    {
        dimensions[2] = 1;     //Greyscale images
    }
    //For gray, return an x by y array, not an x by y by 1
    int num_dims  = (png_get_color_type(png_ptr, info_ptr)
                                & PNG_COLOR_MASK_COLOR) ? 3 : 2;

    PyArrayObject *A = NULL;
    if (float_result) {
        double max_value = (1 << bit_depth) - 1;
        PyArrayObject *A = (PyArrayObject *) PyArray_SimpleNew(
            num_dims, dimensions, PyArray_FLOAT);

        if (A == NULL)
        {
            throw Py::MemoryError("Could not allocate image array");
        }

        for (png_uint_32 y = 0; y < height; y++)
        {
            png_byte* row = row_pointers[y];
            for (png_uint_32 x = 0; x < width; x++)
            {
                size_t offset = y * A->strides[0] + x * A->strides[1];
                if (bit_depth == 16)
                {
                    png_uint_16* ptr = &reinterpret_cast<png_uint_16*>(row)[x * dimensions[2]];
                    for (png_uint_32 p = 0; p < (png_uint_32)dimensions[2]; p++)
                    {
                        *(float*)(A->data + offset + p*A->strides[2]) = (float)(ptr[p]) / max_value;
                    }
                }
                else
                {
                    png_byte* ptr = &(row[x * dimensions[2]]);
                    for (png_uint_32 p = 0; p < (png_uint_32)dimensions[2]; p++)
                    {
                        *(float*)(A->data + offset + p*A->strides[2]) = (float)(ptr[p]) / max_value;
                    }
                }
            }
        }
    } else {
        A = (PyArrayObject *) PyArray_SimpleNew(num_dims, dimensions, NPY_UBYTE);

        if (A == NULL)
        {
            throw Py::MemoryError("Could not allocate image array");
        }

        for (png_uint_32 y = 0; y < height; y++)
        {
            png_byte* row = row_pointers[y];
            for (png_uint_32 x = 0; x < width; x++)
            {
                size_t offset = y * A->strides[0] + x * A->strides[1];
                if (bit_depth == 16)
                {
                    png_uint_16* ptr = &reinterpret_cast<png_uint_16*>(row)[x * dimensions[2]];
                    for (png_uint_32 p = 0; p < (png_uint_32)dimensions[2]; p++)
                    {
                        *(png_byte*)(A->data + offset + p*A->strides[2]) = ptr[p] >> 8;
                    }
                }
                else
                {
                    png_byte* ptr = &(row[x * dimensions[2]]);
                    for (png_uint_32 p = 0; p < (png_uint_32)dimensions[2]; p++)
                    {
                        *(png_byte*)(A->data + offset + p*A->strides[2]) = ptr[p];
                    }
                }
            }
        }
コード例 #9
0
static gboolean
gst_gl_differencematte_loader (GstGLFilter * filter)
{
  GstGLDifferenceMatte *differencematte = GST_GL_DIFFERENCEMATTE (filter);

  png_structp png_ptr;
  png_infop info_ptr;
  guint sig_read = 0;
  png_uint_32 width = 0;
  png_uint_32 height = 0;
  gint bit_depth = 0;
  gint color_type = 0;
  gint interlace_type = 0;
  png_FILE_p fp = NULL;
  guint y = 0;
  guchar **rows = NULL;
  gint filler;

  if (!GST_GL_BASE_FILTER (filter)->context)
    return TRUE;

  if ((fp = fopen (differencematte->location, "rb")) == NULL)
    LOAD_ERROR ("file not found");

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

  if (png_ptr == NULL) {
    fclose (fp);
    LOAD_ERROR ("failed to initialize the png_struct");
  }

  png_set_error_fn (png_ptr, NULL, NULL, user_warning_fn);

  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);
    LOAD_ERROR ("failed to initialize the memory for image information");
  }

  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, int_p_NULL, int_p_NULL);

  if (color_type == PNG_COLOR_TYPE_RGB) {
    filler = 0xff;
    png_set_filler (png_ptr, filler, PNG_FILLER_AFTER);
    color_type = PNG_COLOR_TYPE_RGB_ALPHA;
  }

  if (color_type != PNG_COLOR_TYPE_RGB_ALPHA) {
    fclose (fp);
    png_destroy_read_struct (&png_ptr, png_infopp_NULL, png_infopp_NULL);
    LOAD_ERROR ("color type is not rgb");
  }

  differencematte->pbuf_width = width;
  differencematte->pbuf_height = height;

  differencematte->pixbuf =
      (guchar *) malloc (sizeof (guchar) * width * height * 4);

  rows = (guchar **) malloc (sizeof (guchar *) * height);

  for (y = 0; y < height; ++y)
    rows[y] = (guchar *) (differencematte->pixbuf + y * width * 4);

  png_read_image (png_ptr, rows);

  free (rows);

  png_read_end (png_ptr, info_ptr);
  png_destroy_read_struct (&png_ptr, &info_ptr, png_infopp_NULL);
  fclose (fp);

  return TRUE;
}
コード例 #10
0
ファイル: lecteur.cpp プロジェクト: benchekroun/coursm1
struct gl_texture_t *ReadPNGFromFile (const char *filename) 
{
  
  FILE *fp;
  png_byte magic[8];
  
  /* 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;
  }
  
  png_structp 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 */
  png_infop 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 */
  struct gl_texture_t *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 (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);

  int bit_depth, color_type;
  
  /* 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_uint_32 w, h;
  
  png_get_IHDR (png_ptr, info_ptr, &w, &h, &bit_depth,&color_type, NULL, NULL, NULL);
  texinfo->width = w;
  texinfo->height = h;
  switch (color_type) {
  case PNG_COLOR_TYPE_GRAY:
    texinfo->format = GL_LUMINANCE;
    texinfo->internalFormat = 1;
    break;
    
  case PNG_COLOR_TYPE_GRAY_ALPHA:
    texinfo->format = GL_LUMINANCE_ALPHA;
    texinfo->internalFormat = 2;
    break;
    
  case PNG_COLOR_TYPE_RGB:
    texinfo->format = GL_RGB;
    texinfo->internalFormat = 3;
    break;

  case PNG_COLOR_TYPE_RGB_ALPHA:
    texinfo->format = GL_RGBA;
    texinfo->internalFormat = 4;
    break;

  default:
    /* Badness */
    break;
  }
  /* We can now allocate memory for storing pixel data */
  texinfo->texels = (GLubyte *)malloc (sizeof (GLubyte)*texinfo->width*texinfo->height*texinfo->internalFormat);
  
  png_bytep *row_pointers;
  
  /* Setup a pointer array.  Each one points at the begening of a row. */
  row_pointers = (png_bytep *)malloc (sizeof (png_bytep) * texinfo->height);
  
  for (int 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);
  
  /* We don't need row pointers anymore */
  free (row_pointers);
  
  return(texinfo);
  
}
コード例 #11
0
static GF_Err PNG_ProcessData(GF_MediaDecoder *ifcg, 
		char *inBuffer, u32 inBufferLength,
		u16 ES_ID,
		char *outBuffer, u32 *outBufferLength,
		u8 PaddingBits, u32 mmlevel)
{
	png_struct *png_ptr;
	png_info *info_ptr;
	png_byte **rows;
	u32 i, stride;

	PNGCTX();
	if ((inBufferLength<8) || png_sig_cmp(inBuffer, 0, 8) ) return GF_NON_COMPLIANT_BITSTREAM;

	ctx->in_data = inBuffer;
	ctx->in_length = inBufferLength;
	ctx->current_pos = 0;

	png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp) ctx, NULL, NULL);
	if (!png_ptr) return GF_IO_ERR;
	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 GF_IO_ERR;
	}
	if (setjmp(png_ptr->jmpbuf)) {
		png_destroy_info_struct(png_ptr,(png_infopp) & info_ptr);
		png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
		return GF_IO_ERR;
	}
    png_set_read_fn(png_ptr, ctx, (png_rw_ptr) user_read_data);
	png_set_error_fn(png_ptr, ctx, (png_error_ptr) user_error_fn, NULL);

	png_read_info(png_ptr, info_ptr);

	/*unpaletize*/
	if (info_ptr->color_type==PNG_COLOR_TYPE_PALETTE) {
		png_set_expand(png_ptr);
		png_read_update_info(png_ptr, info_ptr);
	}
	if (info_ptr->num_trans) {
		png_set_tRNS_to_alpha(png_ptr);
		png_read_update_info(png_ptr, info_ptr);
	}

	ctx->BPP = info_ptr->pixel_depth / 8;
	ctx->width = info_ptr->width;
	ctx->height = info_ptr->height;

	switch (ctx->BPP) {
	case 1:
		ctx->pixel_format = GF_PIXEL_GREYSCALE;
		break;
	case 2:
		ctx->pixel_format = GF_PIXEL_ALPHAGREY;
		break;
	case 3:
		ctx->pixel_format = GF_PIXEL_RGB_24;
		break;
	case 4:
		ctx->pixel_format = GF_PIXEL_RGBA;
		break;
	}

	/*new cfg, reset*/
	if (ctx->out_size != ctx->width * ctx->height * ctx->BPP) {
		ctx->out_size = ctx->width * ctx->height * ctx->BPP;
		*outBufferLength = ctx->out_size;
		png_destroy_info_struct(png_ptr,(png_infopp) & info_ptr);
		png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
		return GF_BUFFER_TOO_SMALL;
	}

	/*read*/
	stride = png_get_rowbytes(png_ptr, info_ptr);
	rows = (png_bytepp) malloc(sizeof(png_bytep) * ctx->height);
	for (i=0; i<ctx->height; i++) {
		rows[i] = outBuffer + i*stride;
	}
	png_read_image(png_ptr, rows);
	png_read_end(png_ptr, NULL);
	free(rows);

	png_destroy_info_struct(png_ptr,(png_infopp) & info_ptr);
	png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
	*outBufferLength = ctx->out_size;

	
	return GF_OK;
}
コード例 #12
0
GLubyte* 
glmReadPNG(const char* filename, GLboolean alpha, int* width_ret, 
           int* height_ret, int* type_ret)
{
    png_structp png_ptr;
    png_infop info_ptr;
    png_uint_32 width, height;
    
    int bit_depth, color_type, interlace_type;
    FILE *fp;
    unsigned char *buffer;
    int y, bytes_per_row;
    int channels;
    int format;
    png_bytepp row_pointers;
    
    if ((fp = fopen(filename, "rb")) == NULL) {
        pngerror = ERR_OPEN;
        return NULL;
    }
    
    /* 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,
      (void *)user_error_ptr, user_error_fn, user_warning_fn);*/
    
    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
                                     NULL, err_callback, warn_callback);
    
    if (png_ptr == NULL) {
        pngerror = ERR_MEM;
        fclose(fp);
        return 0;
    }
    
    /* Allocate/initialize the memory for image information.  REQUIRED. */
    info_ptr = png_create_info_struct(png_ptr);
    if (info_ptr == NULL) {
        pngerror = ERR_MEM;
        fclose(fp);
        png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
        return 0;
    }
    
    /* 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.
     */
    
    buffer = NULL;
    
    if (setjmp(setjmp_buffer)) {
        pngerror = ERR_PNGLIB;
        /* 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 */
        
        if (buffer) free(buffer);
        return NULL;
    }
    
    /* Set up the input control if you are using standard C streams */
    png_init_io(png_ptr, fp);
    
    /* 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, NULL, 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 th
     * 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_expand(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_expand(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_expand(png_ptr);
    
    /* Add filler (or alpha) byte (before/after each RGB triplet) */
    /* png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER); */
    
    png_read_update_info(png_ptr, info_ptr);
    
    channels = png_get_channels(png_ptr, info_ptr);
    
    /* allocate the memory to hold the image using the fields of info_ptr. */
    
    bytes_per_row = png_get_rowbytes(png_ptr, info_ptr);
    
    
    buffer = (unsigned char*) malloc(bytes_per_row*height);
    
    format = channels;
    
    row_pointers = (png_bytepp) malloc(height*sizeof(png_bytep));
    for (y = 0; y < height; y++) {
        row_pointers[height-y-1] = buffer + y*bytes_per_row;
    }
    
    png_read_image(png_ptr, row_pointers);
    png_read_end(png_ptr, info_ptr);
    
    free(row_pointers);
    
    /* clean up after the read, and free any memory allocated - REQUIRED */
    png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
    
    /* close the file */
    fclose(fp);
    
    /* that's it */
    if (buffer) {
        *width_ret = width;
        *height_ret = height;
        switch(format) {
        case 1:
            *type_ret = GL_LUMINANCE;
            break;
        case 2:
            *type_ret = GL_LUMINANCE_ALPHA;
            break;
        case 3:
            *type_ret = GL_RGB;
            break;
        case 4:
            *type_ret = GL_RGBA;
            break;
        }
        pngerror = ERR_NO_ERROR;
    }
    else {
        pngerror = ERR_MEM;
    }
    return buffer;
}
コード例 #13
0
ファイル: support.c プロジェクト: PDKK/doubleHexapod
int loadPNG(const char *filename)
{

    GLuint texture;
    png_structp png_ptr = NULL;
    png_infop info_ptr = NULL;
    png_bytep *row_pointers = NULL;
    int bitDepth, colourType;

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

    if (!pngFile)
        return 0;

    png_byte sig[8];

    fread(&sig, 8, sizeof(png_byte), pngFile);
    rewind(pngFile);
    if (!png_check_sig(sig, 8)) {
        printf("png sig failure\n");
        return 0;
    }

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

    if (!png_ptr) {
        printf("png ptr not created\n");
        return 0;
    }

    if (setjmp(png_jmpbuf(png_ptr))) {
        printf("set jmp failed\n");
        return 0;
    }

    info_ptr = png_create_info_struct(png_ptr);

    if (!info_ptr) {
        printf("cant get png info ptr\n");
        return 0;
    }

    png_init_io(png_ptr, pngFile);
    png_read_info(png_ptr, info_ptr);
    bitDepth = png_get_bit_depth(png_ptr, info_ptr);
    colourType = png_get_color_type(png_ptr, info_ptr);

    if (colourType == PNG_COLOR_TYPE_PALETTE)
        png_set_palette_to_rgb(png_ptr);
    if (colourType == PNG_COLOR_TYPE_GRAY && bitDepth < 8)
        //png_set_gray_1_2_4_to_8(png_ptr);
        png_set_expand_gray_1_2_4_to_8(png_ptr);  // thanks to Jesse Jaara for bug fix for newer libpng...
    if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
        png_set_tRNS_to_alpha(png_ptr);

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

    png_read_update_info(png_ptr, info_ptr);

    png_uint_32 width, height;
    png_get_IHDR(png_ptr, info_ptr, &width, &height,
                 &bitDepth, &colourType, NULL, NULL, NULL);

    int components;		// = GetTextureInfo(colourType);
    switch (colourType) {
    case PNG_COLOR_TYPE_GRAY:
        components = 1;
        break;
    case PNG_COLOR_TYPE_GRAY_ALPHA:
        components = 2;
        break;
    case PNG_COLOR_TYPE_RGB:
        components = 3;
        break;
    case PNG_COLOR_TYPE_RGB_ALPHA:
        components = 4;
        break;
    default:
        components = -1;
    }

    if (components == -1) {
        if (png_ptr)
            png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
        printf("%s broken?\n", filename);
        return 0;
    }

    GLubyte *pixels =
        (GLubyte *) malloc(sizeof(GLubyte) * (width * height * components));
    row_pointers = (png_bytep *) malloc(sizeof(png_bytep) * height);

    for (int i = 0; i < height; ++i)
        row_pointers[i] =
            (png_bytep) (pixels + (i * width * components));

    png_read_image(png_ptr, row_pointers);
    png_read_end(png_ptr, NULL);

    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    GLuint glcolours;
    (components == 4) ? (glcolours = GL_RGBA) : (0);
    (components == 3) ? (glcolours = GL_RGB) : (0);
    (components == 2) ? (glcolours = GL_LUMINANCE_ALPHA) : (0);
    (components == 1) ? (glcolours = GL_LUMINANCE) : (0);

    //printf("%s has %i colour components\n",filename,components);
    //glTexImage2D(GL_TEXTURE_2D, 0, components, width, height, 0, glcolours, GL_UNSIGNED_BYTE, pixels);
    glTexImage2D(GL_TEXTURE_2D, 0, glcolours, width, height, 0, glcolours,
                 GL_UNSIGNED_BYTE, pixels);

    png_destroy_read_struct(&png_ptr, &info_ptr, NULL);

    fclose(pngFile);
    free(row_pointers);
    free(pixels);

    return texture;

}
コード例 #14
0
int
SplashDecodePng(Splash * splash, png_rw_ptr read_func, void *io_ptr)
{
    int stride;
    ImageFormat srcFormat;
    png_uint_32 i, rowbytes;
    png_bytepp row_pointers = NULL;
    png_bytep image_data = NULL;
    int success = 0;
    double gamma;

    png_structp png_ptr = NULL;
    png_infop info_ptr = NULL;

    png_uint_32 width, height;
    int bit_depth, color_type;

    ImageRect srcRect, dstRect;

    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    if (!png_ptr) {
        goto done;
    }

    info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr) {
        goto done;
    }

#ifdef __APPLE__
    /* use setjmp/longjmp versions that do not save/restore the signal mask */
    if (_setjmp(png_set_longjmp_fn(png_ptr, _longjmp, sizeof(jmp_buf)))) {
#else
    if (setjmp(png_jmpbuf(png_ptr))) {
#endif
        goto done;
    }

    png_set_read_fn(png_ptr, io_ptr, read_func);

    png_set_sig_bytes(png_ptr, SIG_BYTES);      /* we already read the 8 signature bytes */

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

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

    /* expand palette images to RGB, low-bit-depth grayscale images to 8 bits,
     * transparency chunks to full alpha channel; strip 16-bit-per-sample
     * images to 8 bits per sample; and convert grayscale to RGB[A]
     * this may be sub-optimal but this simplifies implementation */

    png_set_expand(png_ptr);
    png_set_tRNS_to_alpha(png_ptr);
    png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
    png_set_strip_16(png_ptr);
    png_set_gray_to_rgb(png_ptr);

    if (png_get_gAMA(png_ptr, info_ptr, &gamma))
        png_set_gamma(png_ptr, 2.2, gamma);

    png_set_interlace_handling(png_ptr);
    png_read_update_info(png_ptr, info_ptr);

    rowbytes = png_get_rowbytes(png_ptr, info_ptr);

    if (!SAFE_TO_ALLOC(rowbytes, height)) {
        goto done;
    }

    if ((image_data = (unsigned char *) malloc(rowbytes * height)) == NULL) {
        goto done;
    }

    if (!SAFE_TO_ALLOC(height, sizeof(png_bytep))) {
        goto done;
    }
    if ((row_pointers = (png_bytepp) malloc(height * sizeof(png_bytep)))
            == NULL) {
        goto done;
    }

    for (i = 0; i < height; ++i)
        row_pointers[i] = image_data + i * rowbytes;

    png_read_image(png_ptr, row_pointers);

    SplashCleanup(splash);

    splash->width = width;
    splash->height = height;

    if (!SAFE_TO_ALLOC(splash->width, splash->imageFormat.depthBytes)) {
        goto done;
    }
    stride = splash->width * splash->imageFormat.depthBytes;

    if (!SAFE_TO_ALLOC(splash->height, stride)) {
        goto done;
    }
    splash->frameCount = 1;
    splash->frames = (SplashImage *)
        malloc(sizeof(SplashImage) * splash->frameCount);

    if (splash->frames == NULL) {
        goto done;
    }

    splash->loopCount = 1;
    splash->frames[0].bitmapBits = malloc(stride * splash->height);
    if (splash->frames[0].bitmapBits == NULL) {
        free(splash->frames);
        goto done;
    }
    splash->frames[0].delay = 0;

    /* FIXME: sort out the real format */
    initFormat(&srcFormat, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF);
    srcFormat.byteOrder = BYTE_ORDER_MSBFIRST;

    initRect(&srcRect, 0, 0, width, height, 1, rowbytes,
        image_data, &srcFormat);
    initRect(&dstRect, 0, 0, width, height, 1, stride,
        splash->frames[0].bitmapBits, &splash->imageFormat);
    convertRect(&srcRect, &dstRect, CVT_COPY);

    SplashInitFrameShape(splash, 0);

    png_read_end(png_ptr, NULL);
    success = 1;

  done:
    free(row_pointers);
    free(image_data);
    png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
    return success;
}

int
SplashDecodePngStream(Splash * splash, SplashStream * stream)
{
    unsigned char sig[SIG_BYTES];
    int success = 0;

    stream->read(stream, sig, SIG_BYTES);
    if (png_sig_cmp(sig, 0, SIG_BYTES)) {
        goto done;
    }
    success = SplashDecodePng(splash, my_png_read_stream, stream);

  done:
    return success;
}
コード例 #15
0
ファイル: ImageUtils.cpp プロジェクト: kristofe/GameEngine
void read_png_file(const char* file_name,Texture& tex, bool flipY)
{
	//int x, y;
	int width, height;
	//png_byte color_type;
	//png_byte bit_depth;
	//png_structp png_ptr;
	//png_infop info_ptr;
	//int number_of_passes;
	//header for testing if it is a png
	png_byte header[8];

	//open file as binary
	FILE *fp = fopen(file_name, "rb");
	if (!fp) {
	return;
	}

	//read the header
	fread(header, 1, 8, fp);

	//test if png
	int is_png = !png_sig_cmp(header, 0, 8);
	if (!is_png) {
	fclose(fp);
	return;
	}

	//create png struct
	png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL,
	  NULL, NULL);
	if (!png_ptr) {
	fclose(fp);
	return;
	}

	//create png info struct
	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);
	fclose(fp);
	return;
	}

	//create png info struct
	png_infop end_info = png_create_info_struct(png_ptr);
	if (!end_info) {
	png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL);
	fclose(fp);
	return;
	}

	//png error stuff, not sure libpng man suggests this.
	if (setjmp(png_jmpbuf(png_ptr))) {
	png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
	fclose(fp);
	return;
	}

	//init png reading
	png_init_io(png_ptr, fp);

	//let libpng know you already read the first 8 bytes
	png_set_sig_bytes(png_ptr, 8);

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

	//variables to pass to get info
	int bit_depth, color_type;
	png_uint_32 twidth, theight;

	// get info about png
	png_get_IHDR(png_ptr, info_ptr, &twidth, &theight, &bit_depth, &color_type,
	  NULL, NULL, NULL);

	//update width and height based on png info
	width = twidth;
	height = theight;

	// Update the png info struct.
	png_read_update_info(png_ptr, info_ptr);

	// Row size in bytes.
	int rowbytes = png_get_rowbytes(png_ptr, info_ptr);

	// Allocate the image_data as a big block, to be given to opengl
	png_byte *image_data = new png_byte[rowbytes * height];
	if (!image_data) {
	//clean up memory and close stuff
	png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
	fclose(fp);
	return;
	}

	//row_pointers is for pointing to image_data for reading the png with libpng
	png_bytep *row_pointers = new png_bytep[height];
	if (!row_pointers) {
	//clean up memory and close stuff
	png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
	delete[] image_data;
	fclose(fp);
	return ;
	}
	// set the individual row_pointers to point at the correct offsets of image_data
	if(!flipY){
		for (int i = 0; i < height; ++i)
			row_pointers[i] = image_data + i * rowbytes;
	}
	else
	{
		for (int i = 0; i < height; ++i)
			row_pointers[height - 1 - i] = image_data + i * rowbytes;
	}
	
	//read the png into image_data through row_pointers
	png_read_image(png_ptr, row_pointers);

	/*

	  // set the individual row_pointers to point at the correct offsets of image_data
	  for (int i = 0; i < height; ++i)
		row_pointers[height - 1 - i] = (png_bytep)(image_data + i * rowbytes);

	///////////////////////////////////////////////////////////////
	*/
	//png_read_image(png_ptr, row_pointers);
	//png_set_rows(png_ptr,info_ptr,row_pointers);
	//png_read_png(png_ptr,info_ptr,/*PNG_TRANSFORM_BGR |*/ PNG_TRANSFORM_INVERT_ALPHA,NULL);
	//png_destroy_read_struct(&png_ptr, &info_ptr,NULL);

	unsigned int* pixels = (unsigned int*)malloc(rowbytes * height);
	memcpy(pixels,image_data,rowbytes * height);
	tex.mPixelData = pixels;
	tex.mWidth = width;
	tex.mHeight = height;
	if(color_type == PNG_COLOR_TYPE_RGB_ALPHA)
	{
		tex.mNumberOfColors = 4;
	}
	else if(color_type == PNG_COLOR_TYPE_RGB)
	{
		tex.mNumberOfColors = 3;
	}
	else
	{
		tex.mNumberOfColors = 3;
	}
	tex.mHasAlpha = tex.mNumberOfColors==4?true:false;
	tex.mBitsPerPixel = tex.mNumberOfColors * bit_depth;
	if(tex.mNumberOfColors == 4)
	{
		tex.mPixelFormat  = GL_RGBA;
	}
	else
	{
		tex.mPixelFormat  = GL_RGB;
	}
	//clean up memory and close stuff
	png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
	delete[] image_data;
	delete[] row_pointers;
	fclose(fp);
}
コード例 #16
0
ファイル: png.c プロジェクト: elechak/blue
static NATIVECALL(png_new){
    Link * args = array_getArray(Arg);

    unsigned char pngheader[HEADERSIZE];
    png_structp png;
    png_infop info;
    png_bytep * row_pointers;
    png_byte* row ;

    FILE *fp;
    int  y, width, height;

    /* open the file args[0] is the filename */
    string_t filename_string = object_getString(args[0]);
    fp = fopen(filename_string->data , "rb");
    if (! fp){
        return exception("CouldNotOpenFile", NULL, NULL);
    }

    /* read the png header and ensure it is a png */
	fread(pngheader, 1, HEADERSIZE, fp);
	if (png_sig_cmp(pngheader, 0, HEADERSIZE)){
        return exception("NotPNG", NULL, NULL);
    }

	png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    png_set_sig_bytes(png, HEADERSIZE);
	info = png_create_info_struct(png);

	png_init_io(png, fp);

	png_read_info(png, info);

    Link obj = object_create(image_type);

    Image self = obj->value.vptr;

    self->width = info->width;

    self->height = info->height;

	width = info->width;

	height = info->height;

    //info->bit_depth;
    //info->channels;
	//info->color_type;
    //printf(" bit depth:%i    channels:%i    color type:%i   rowbytes:%i\n", info->bit_depth, info->channels, info->color_type , info->rowbytes);


    /* read png information */
	png_read_update_info(png, info);

    /* allocate memory for rows */
	row_pointers = malloc(sizeof(png_bytep) * height);
	for (y=0; y<height; y++) row_pointers[y] = malloc(info->rowbytes);

    /* read image into allocated memory */
	png_read_image(png, row_pointers);

    fclose(fp);

    png_byte * pdata;

    self->format = info->channels;
    self->data = pdata = malloc(self->width * self->height * self->format);
    for (y=0; y<height; y++) {
        row = row_pointers[height-y-1];
        memcpy(pdata,row, self->width * self->format);
        pdata+=self->width * self->format;
        free(row);
    }

    free(row_pointers);
    png_destroy_read_struct(&png, &info, NULL);

    return obj;
}
コード例 #17
0
	uint8_t* GraphicsTexture::loadImage()
	{
		Pegas_log_info("GraphicsTexture::loadImage");

		Resource::AutoDispose autoDispose(mResource);
		if (mResource.open() != STATUS_OK)
		{
			Pegas_log_error("mResource.open failed");
			return NULL;
		}

		png_byte header[8];
		if (mResource.read(header, sizeof(header)) != STATUS_OK)
		{
			Pegas_log_error("mResource.read failed");
			return NULL;
		}

		if (png_sig_cmp(header, 0, 8) != 0)
		{
			Pegas_log_error("png_sig_cmp failed, header param: %s", header);
			return NULL;
		}

		png_structp pngMain = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
		if (!pngMain) {
			Pegas_log_error("png_create_read_struct failed");
			return NULL;
		}
		png_infop pngInfo = png_create_info_struct(pngMain);
		if (!pngInfo) {
			Pegas_log_error("png_create_info_struct failed");
			return NULL;
		}
		png_set_read_fn(pngMain, &mResource, callback_read);
		if (setjmp(png_jmpbuf(pngMain))) {
			Pegas_log_error("setjmp failed");
			return NULL;
		}
		png_set_sig_bytes(pngMain, 8);
		png_read_info(pngMain, pngInfo);
		png_int_32 depth, colorType;
		png_uint_32 width, height;
		png_get_IHDR(pngMain, pngInfo, &width, &height, &depth, &colorType, NULL,
				NULL, NULL);
		mWidth = width;
		mHeight = height;
		bool transparency = false;
		// Creates a full alpha channel if transparency is encoded as
		// an array of palette entries or a single transparent color.
		if (png_get_valid(pngMain, pngInfo, PNG_INFO_tRNS)) {
			png_set_tRNS_to_alpha(pngMain);
			transparency = true;

			Pegas_log_error("png_get_valid failed");
			return NULL;
		}
		// Expands PNG with less than 8bits per channel to 8bits.
		if (depth < 0) {
			png_set_packing(pngMain);
			// Shrinks PNG with 16bits per color channel down to 8bits.
		} else if (depth == 16) {
			png_set_strip_16(pngMain);
		}

		// Indicates that image needs conversion to RGBA if	needed.
		switch (colorType) {
		case PNG_COLOR_TYPE_PALETTE:
			png_set_palette_to_rgb(pngMain);
			mFormat = transparency ? GL_RGBA : GL_RGB;
			break;
		case PNG_COLOR_TYPE_RGB:
			mFormat = transparency ? GL_RGBA : GL_RGB;
			break;
		case PNG_COLOR_TYPE_RGBA:
			mFormat = GL_RGBA;
			break;
		case PNG_COLOR_TYPE_GRAY:
			png_set_expand_gray_1_2_4_to_8(pngMain);
			mFormat = transparency ? GL_LUMINANCE_ALPHA : GL_LUMINANCE;
			break;
		case PNG_COLOR_TYPE_GA:
			png_set_expand_gray_1_2_4_to_8(pngMain);
			mFormat = GL_LUMINANCE_ALPHA;
			break;
		}
		png_read_update_info(pngMain, pngInfo);
		png_int_32 rowSize = png_get_rowbytes(pngMain, pngInfo);
		if (rowSize <= 0) {
			Pegas_log_error("invalid png row size: %d", rowSize);
			return NULL;
		}
		png_byte* imageBuffer = new png_byte[rowSize * height];
		if (!imageBuffer) {
			Pegas_log_error("can not allocate image buffer");
			return NULL;
		}
		png_bytep* rowPtrs = new png_bytep[height];
		if (!rowPtrs) {
			Pegas_log_error("can not allocate row pointers");
			//TODO: use smart pointer for this
			delete[] imageBuffer;

			return NULL;
		}
		for (int32_t i = 0; i < height; ++i) {
			rowPtrs[height - (i + 1)] = imageBuffer + (i * rowSize);
		}
		png_read_image(pngMain, rowPtrs);
		png_destroy_read_struct(&pngMain, &pngInfo, NULL);
		delete[] rowPtrs;

		return imageBuffer;
}
コード例 #18
0
//
// Reads the image
//
void PNGReader::read(ImageFile * image)
{
	volatile unsigned char ** volatile rowPointers = NULL;
	png_struct * pngPtr = NULL;
	png_info * infoPtr = NULL;
	byte * data = NULL;

	try
	{
		int colorType, bitDepth;
		bool hasAlpha = false;
		uint bytesPerElement;
		ImageFormat format;
		unsigned long w, h;
		unsigned rowbytes;

		// Initialize the PNG library
		pngPtr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, pngErrorFunc, pngWarningFunc);
		if (unlikely(!pngPtr))
			throw Exception(QString("%1: png_create_read_struct() failed").arg(m_File.fileName()));

		// Initialize the PNG info struct
		infoPtr = png_create_info_struct(pngPtr);
		if (unlikely(!infoPtr))
			throw Exception(QString("%1: png_create_info_struct() failed").arg(m_File.fileName()));

		// Setup error handler
		if (unlikely(setjmp(png_jmpbuf(pngPtr)) != 0))
			throw Exception(QString("%1: PNG decompression failed").arg(m_File.fileName()));

		// Setup file reading
		png_set_read_fn(pngPtr, &m_File, pngReadFunc);
		png_set_sig_bytes(pngPtr, 8);
		png_read_info(pngPtr, infoPtr);
		png_get_IHDR(pngPtr, infoPtr, &w, &h, &bitDepth, &colorType, NULL, NULL, NULL);

		// Setup 16 bit -> 8 bit conversion
		if (bitDepth > 8) 
			png_set_strip_16(pngPtr);

		// Translate transparency to alpha channel
  		if (png_get_valid(pngPtr, infoPtr, PNG_INFO_tRNS))
		{
			png_set_tRNS_to_alpha(pngPtr);
			hasAlpha = true;
		}

		// Setup gamma correction
		double gamma;
		if (png_get_gAMA(pngPtr, infoPtr, &gamma))
			png_set_gamma(pngPtr, 2.2, gamma);
		else
			png_set_gamma(pngPtr, 2.2, 0.45455);

		// We want at least 8-bit
		if (bitDepth < 8)
		{
			if ((colorType == PNG_COLOR_TYPE_GRAY || colorType == PNG_COLOR_TYPE_GRAY_ALPHA))
				png_set_gray_1_2_4_to_8(pngPtr);
			else
				png_set_packing(pngPtr);
		}

		// Convert paletted images to RGB
		if (colorType == PNG_COLOR_TYPE_PALETTE)
		{
			png_set_palette_to_rgb(pngPtr);
			colorType = hasAlpha ? PNG_COLOR_TYPE_RGBA : PNG_COLOR_TYPE_RGB;
		}

		// Convert gray/alpha images to RGB
		if (colorType == PNG_COLOR_TYPE_GRAY_ALPHA ||
			(colorType == PNG_COLOR_TYPE_GRAY && hasAlpha))
		{
			png_set_gray_to_rgb(pngPtr);
			colorType = PNG_COLOR_TYPE_RGB_ALPHA;
		}

		// Add dummy alpha channel for RGB images
		if (colorType == PNG_COLOR_TYPE_RGB && !hasAlpha)
		{
			png_set_filler(pngPtr, 0xFF, PNG_FILLER_BEFORE);
			hasAlpha = true;
		}
		else if (colorType == PNG_COLOR_TYPE_RGB_ALPHA)
			hasAlpha = true;

		// Select pixel format
		switch (colorType)
		{
		case PNG_COLOR_TYPE_PALETTE:
		case PNG_COLOR_TYPE_GRAY_ALPHA:
			Q_ASSERT(false);	// Should be handled in the code above
			break;

		case PNG_COLOR_TYPE_GRAY:
			bytesPerElement = 1;
			format = R8_UNORM;
			break;

		default:
			Q_ASSERT(hasAlpha);	// Should be handled in the code above
			bytesPerElement = 4;
			format = RGBA8_UNORM;
			break;
		}

		// Re-configure PNG reading to include configured conversions
		png_read_update_info(pngPtr, infoPtr);
		rowbytes = png_get_rowbytes(pngPtr, infoPtr);

		// Set basic image info
		setImageSize(image, w, h);
		setImageDepth(image, 0);
		setImageMipLevels(image, 1);
		setImageFaces(image, 0);
		setImageFormat(image, format);
		setImageElementSize(image, bytesPerElement);

		// Allocate memory for image data
		data = new byte[w * h * bytesPerElement];
		if (unlikely(!data))
			throw Exception("Out of memory.");

		// Allocate array of row pointers
		rowPointers = new volatile unsigned char * [h];
		for (unsigned j = 0; j < h; j++)
			rowPointers[j] = data + j * rowbytes;

		// Read the image
		png_read_image(pngPtr, (png_byte **)rowPointers);

		// Store image information
		appendImageLevelData(image, data);
		data = NULL;

		// Free memory
		png_destroy_read_struct(&pngPtr, &infoPtr, NULL);
		pngPtr = NULL;
	}
	catch (...)
	{
		delete[] rowPointers;
		delete[] data;

		if (pngPtr)
		{
			if (infoPtr)
				png_destroy_read_struct(&pngPtr, &infoPtr, NULL);
			else
				png_destroy_read_struct(&pngPtr, NULL, NULL);
		}	

		throw;
	}

	delete[] rowPointers;
}
コード例 #19
0
ファイル: plugin.cpp プロジェクト: AEonZR/GtkRadiant
void LoadImage (const char *filename, unsigned char **pic, int *width, int *height)
{
    png_byte** row_pointers;
    unsigned char *fbuffer = NULL;
    png_bytep p_fbuffer;

    int nLen = g_FileSystemTable.m_pfnLoadFile( (char *)filename, (void **)&fbuffer, 0 );
    if (nLen == -1)
        return;

    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)
    {
        g_FuncTable.m_pfnSysPrintf ("libpng error: png_create_read_struct\n");
        return;
    }

    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);
        g_FuncTable.m_pfnSysPrintf ("libpng error: png_create_info_struct (info_ptr)\n");
        return;
    }

    png_infop end_info = png_create_info_struct(png_ptr);
    if (!end_info) {
        png_destroy_read_struct(&png_ptr, &info_ptr,
                                png_infopp_NULL);
        g_FuncTable.m_pfnSysPrintf ("libpng error: png_create_info_struct (end_info)\n");
        return;
    }

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

    if (setjmp(png_ptr->jmpbuf)) {
        png_destroy_read_struct(&png_ptr, &info_ptr,
                                &end_info);
        if (*pic)
        {
            g_free(*pic);
            free(row_pointers);
        }
        return;
    }

    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)
        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 ( ! ( 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);

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

    // allocate the pixel buffer, and the row pointers
    int size = (*width)*(*height)*4;
    // still have to use that g_malloc heresy
    *pic = (unsigned char *)g_malloc(size);
    row_pointers = (png_byte**) malloc((*height) * sizeof(png_byte*));

    int i;
    for(i = 0; i < (*height); i++)
        row_pointers[i] = (png_byte*)(*pic) + 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);
    g_FileSystemTable.m_pfnFreeFile (fbuffer);
}
コード例 #20
0
static HPDF_STATUS
ReadTransparentPngData  (HPDF_Dict    image,
                         png_structp  png_ptr,
                         png_infop    info_ptr,
                         png_bytep    smask_data)
{
	HPDF_STATUS ret = HPDF_OK;
	HPDF_INT row_len;
	HPDF_UINT i, j;
	png_bytep *row_ptr, row;
	png_byte color_type;
	png_uint_32 height = png_get_image_height(png_ptr, info_ptr);
	png_uint_32 width = png_get_image_width(png_ptr, info_ptr);

	color_type = png_get_color_type(png_ptr, info_ptr);

	if (!(color_type & PNG_COLOR_MASK_ALPHA)) {
		return HPDF_INVALID_PNG_IMAGE;
	}

	row_ptr = HPDF_GetMem (image->mmgr, height * sizeof(png_bytep));
	if (!row_ptr) {
		return HPDF_FAILD_TO_ALLOC_MEM;
	} else {
		png_uint_32 len = png_get_rowbytes(png_ptr, info_ptr);

		for (i = 0; i < (HPDF_UINT)height; i++) {
			row_ptr[i] = HPDF_GetMem(image->mmgr, len);
			if (!row_ptr[i]) {
				for (; i > 0; i--) {
					HPDF_FreeMem (image->mmgr, row_ptr[i]);
				}
				HPDF_FreeMem (image->mmgr, row_ptr);
				return HPDF_FAILD_TO_ALLOC_MEM;
			}
		}
	}

	png_read_image(png_ptr, row_ptr);
	if (image->error->error_no != HPDF_OK) {
		ret = HPDF_INVALID_PNG_IMAGE;
		goto Error;
	}

	switch (color_type) {
		case PNG_COLOR_TYPE_RGB_ALPHA:
			row_len = 3 * width * sizeof(png_byte);
			for (j = 0; j < height; j++) {
				row = row_ptr[j];
				for (i = 0; i < width; i++) {
					memmove(row + (3 * i), row + (4*i), 3);
					smask_data[width * j + i] = row[4 * i + 3];
				}

				if (HPDF_Stream_Write (image->stream, row, row_len) != HPDF_OK) {
					ret = HPDF_FILE_IO_ERROR;
					goto Error;
				}
			}
			break;
		case PNG_COLOR_TYPE_GRAY_ALPHA:
			row_len = width * sizeof(png_byte);
			for (j = 0; j < height; j++) {
				row = row_ptr[j];
				for (i = 0; i < width; i++) {
					row[i] = row[2 * i];
					smask_data[width * j + i] = row[2 * i + 1];
				}

				if (HPDF_Stream_Write (image->stream, row, row_len) != HPDF_OK) {
					ret = HPDF_FILE_IO_ERROR;
					goto Error;
				}
			}
			break;
		default:
			ret = HPDF_INVALID_PNG_IMAGE;
			goto Error;
	}

Error:
	for (i = 0; i < (HPDF_UINT)height; i++) {
		HPDF_FreeMem (image->mmgr, row_ptr[i]);
	}

	HPDF_FreeMem (image->mmgr, row_ptr);
	return ret;
}
コード例 #21
0
/**
 * Read in a PNG file and return it in a buffer pointer.  Make sure to fill
 * in the w & h parameters with the width & height of the image.  Given filename
 * must point to a PNG file.
 */
static Color_t *readPNG(char const *filename,
        int *w, int *h)
{
    int x, y;
    png_byte color_type;
    png_structp png_ptr;
    png_infop info_ptr;
    png_byte bit_depth;
    png_bytep *row_pointers;
    int width, height;
    char header[8];
    FILE *fp;
    Color_t *buffer;

    fp = fopen(filename, "rb");
    if (!fp)
        abort_("Unable to open %s.\n", filename);

    if (fread(header, 1, sizeof(header), fp) != 8)
        abort_("Read mismatch on header.\n");

    if (png_sig_cmp(header, 0, 8))
        abort_("File %s is not recognized as a PNG file.\n", filename);

    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    if (!png_ptr)
        abort_("Unable to create read struct.\n");

    info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr)
        abort_("Unable to create info structure.\n");

    if (setjmp(png_jmpbuf(png_ptr)))
        abort_("Error during read IO\n");

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

    png_read_info(png_ptr, info_ptr);

    width = png_get_image_width(png_ptr, info_ptr);
    height = png_get_image_height(png_ptr, info_ptr);
    color_type = png_get_color_type(png_ptr, info_ptr);
    bit_depth = png_get_bit_depth(png_ptr, info_ptr);
    png_read_update_info(png_ptr, info_ptr);

    if (setjmp(png_jmpbuf(png_ptr)))
        abort_("Error during read_image\n");

    row_pointers = png_malloc(png_ptr, sizeof(png_bytep) * height);
    for (y = 0; y < height; y++)
        row_pointers[y] = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr));

    png_read_image(png_ptr, row_pointers);
    fclose(fp);

    if (png_get_color_type(png_ptr, info_ptr) != PNG_COLOR_TYPE_RGB)
        abort_("Expected RGB image.\n");

    /* Allocate memory for the buffer. */
    buffer = malloc(width * height * sizeof(Color_t));
    if (!buffer)
        abort_("Unable to allocate memory.\n");

    for (y = 0; y < height; y++) {
        png_bytep row = row_pointers[y];
        for (x = 0; x < width; x++) {
            png_bytep px = &(row[x * 3]);
            Color_t *pColor = &buffer[coord_to_ind(x, y, width)];

            pColor->red   = px[0];
            pColor->green = px[1];
            pColor->blue  = px[2];
        }
    }

    for (y = 0; y < height; y++)
        png_free(png_ptr, row_pointers[y]);

    png_free(png_ptr, row_pointers);
    png_destroy_read_struct(&png_ptr, &info_ptr, NULL);

    if (h)
        *h = height;
    if (w)
        *w = width;

    return buffer;
}
コード例 #22
0
ファイル: wzmutils.c プロジェクト: ArtemusRus/warzone2100
PIXMAP *readPixmap(const char *filename)
{
	PIXMAP *gfx;
	png_structp pngp;
	png_infop infop;
	png_uint_32 width, height;
	png_int_32 y, stride;
	int bit_depth, color_type, interlace_type;
	FILE *fp;
	png_bytep *row_pointers;
	const unsigned int sig_length = 8;
	unsigned char header[8];
	unsigned char *image_data;
	unsigned int result;

	if (PNG_LIBPNG_VER_MAJOR != 1 || PNG_LIBPNG_VER_MINOR < 2)
	{
		printf("libpng 1.2.6 or higher required!\n");
		exit(EXIT_FAILURE);
	}
	if (!(fp = fopen(filename, "rb")))
	{
		printf("%s won't open!\n", filename);
		exit(EXIT_FAILURE);
	}
	result = fread(header, 1, sig_length, fp);
	if (result != sig_length)
	{
		printf("Bad file %s\n", filename);
		exit(EXIT_FAILURE);
	}
	if (png_sig_cmp(header, 0, sig_length))
	{
		printf("%s is not a PNG file!\n", filename);
		exit(EXIT_FAILURE);
	}
	if (!(pngp = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL)))
	{
		printf("Failed creating PNG struct reading %s.\n", filename);
		exit(EXIT_FAILURE);
	}
	if (!(infop = png_create_info_struct(pngp)))
	{
		printf("Failed creating PNG info struct reading %s.\n", filename);
		exit(EXIT_FAILURE);
	}
	if (setjmp(pngp->jmpbuf))
	{
		printf("Failed while reading PNG file: %s\n", filename);
		exit(EXIT_FAILURE);
	}
	png_init_io(pngp, fp);
	png_set_sig_bytes(pngp, sig_length);
	png_read_info(pngp, infop);

	/* Transformations to ensure we end up with 32bpp, 4 channel RGBA */
	png_set_strip_16(pngp);
	png_set_gray_to_rgb(pngp);
	png_set_packing(pngp);
	png_set_palette_to_rgb(pngp);
	png_set_tRNS_to_alpha(pngp);
	png_set_filler(pngp, 0xFF, PNG_FILLER_AFTER);
	png_set_gray_1_2_4_to_8(pngp);

	png_read_update_info(pngp, infop);
	png_get_IHDR(pngp, infop, &width, &height, &bit_depth, &color_type, &interlace_type, NULL, NULL);

	stride = png_get_rowbytes(pngp, infop);
	row_pointers = malloc(sizeof(png_bytep) * height);

	image_data = malloc(height * width * 4);
	for (y = 0; y < (int)height; y++)
	{
		row_pointers[y] = image_data + (y * width * 4);
	}

	png_read_image(pngp, row_pointers);
	png_read_end(pngp, infop);
	fclose(fp);

	gfx = malloc(sizeof(*gfx));
	gfx->w = width;
	gfx->h = height;
	gfx->pixels = (char *)image_data;

	png_destroy_read_struct(&pngp, &infop, NULL);
	free(row_pointers);

	return gfx;
}
コード例 #23
0
ファイル: icnsutil.c プロジェクト: SamusAranX/libicns
static int read_png(FILE *fp, png_bytepp buffer, int32_t *bpp, int32_t *width, int32_t *height)
{
	png_structp png_ptr;
	png_infop info;
	png_uint_32 w;
	png_uint_32 h;
	png_bytep *rows;

	int bit_depth;
	int32_t color_type;

	int row;
	int rowsize;

	png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
	if (png_ptr == NULL)
		return FALSE;

	info = png_create_info_struct(png_ptr);
	if (info == NULL)
	{
		png_destroy_read_struct(&png_ptr, NULL, NULL);
		return FALSE;
	}

	if (setjmp(png_jmpbuf(png_ptr)))
	{
		png_destroy_read_struct(&png_ptr, &info, NULL);
		return FALSE;
	}

	png_init_io(png_ptr, fp);

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

	switch (color_type)
	{
		case PNG_COLOR_TYPE_GRAY:
			#ifdef PNG2ICNS_EXPAND_GRAY
			png_set_expand_gray_1_2_4_to_8(png_ptr);
			#else
			png_set_gray_1_2_4_to_8(png_ptr);
			#endif

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

			png_set_gray_to_rgb(png_ptr);
			png_set_add_alpha(png_ptr, 0xff, PNG_FILLER_AFTER);
			break;

		case PNG_COLOR_TYPE_GRAY_ALPHA:
			#ifdef PNG2ICNS_EXPAND_GRAY
			png_set_expand_gray_1_2_4_to_8(png_ptr);
			#else
			png_set_gray_1_2_4_to_8(png_ptr);
			#endif

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

			png_set_gray_to_rgb(png_ptr);
			break;

		case PNG_COLOR_TYPE_PALETTE:
			png_set_palette_to_rgb(png_ptr);

			if (png_get_valid(png_ptr, info, PNG_INFO_tRNS))
				png_set_tRNS_to_alpha(png_ptr);
			else
				png_set_add_alpha(png_ptr, 0xff, PNG_FILLER_AFTER);
			break;

		case PNG_COLOR_TYPE_RGB:
			if (bit_depth == 16) {
				png_set_strip_16(png_ptr);
				bit_depth = 8;
			}

			png_set_add_alpha(png_ptr, 0xff, PNG_FILLER_AFTER);
			break;

		case PNG_COLOR_TYPE_RGB_ALPHA:
			if (bit_depth == 16) {
				png_set_strip_16(png_ptr);
				bit_depth = 8;
			}

			break;
	}

	*width = w;
	*height = h;
	*bpp = bit_depth * 4;

	png_read_update_info(png_ptr, info);

	rowsize = png_get_rowbytes(png_ptr, info);
	rows = malloc (sizeof(png_bytep) * h);
	*buffer = malloc(rowsize * h + 8);

	rows[0] = *buffer;
	for (row = 1; row < h; row++)
	{
		rows[row] = rows[row-1] + rowsize;
	}

	png_read_image(png_ptr, rows);
	png_destroy_read_struct(&png_ptr, &info, NULL);

	free(rows);

	return TRUE;
}
コード例 #24
0
ファイル: rwpng.c プロジェクト: cheoree/pngquant
pngquant_error rwpng_read_image24_libpng(FILE *infile, png24_image *mainprog_ptr)
{
    png_structp  png_ptr = NULL;
    png_infop    info_ptr = NULL;
    png_size_t   rowbytes;
    int          color_type, bit_depth;

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

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

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

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

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

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


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

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


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

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

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

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


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

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

    png_set_interlace_handling(png_ptr);

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

    png_read_update_info(png_ptr, info_ptr);

    rowbytes = png_get_rowbytes(png_ptr, info_ptr);

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

    png_bytepp row_pointers = rwpng_create_row_pointers(info_ptr, png_ptr, mainprog_ptr->rgba_data, mainprog_ptr->height, 0);

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

    png_read_image(png_ptr, row_pointers);

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

    png_read_end(png_ptr, NULL);

#if USE_LCMS
    if (png_get_valid(png_ptr, info_ptr, PNG_INFO_iCCP)) {
        png_uint_32 ProfileLen;
        png_bytep ProfileData;
        int  Compression;
        png_charp ProfileName;

        png_get_iCCP(png_ptr, info_ptr, &ProfileName,
                                        &Compression,
                                        &ProfileData,
                                        &ProfileLen);

        cmsHPROFILE hInProfile = cmsOpenProfileFromMem(ProfileData, ProfileLen);
        cmsHPROFILE hOutProfile = cmsCreate_sRGBProfile();

        cmsHTRANSFORM hTransform = cmsCreateTransform(hInProfile, TYPE_RGBA_8,
                                                    hOutProfile, TYPE_RGBA_8,
                                                    INTENT_PERCEPTUAL, 0);

        // suprisingly, using the same input and output works
        cmsDoTransform(hTransform, mainprog_ptr->rgba_data,
                                   mainprog_ptr->rgba_data,
                                   mainprog_ptr->height * mainprog_ptr->width);

        cmsDeleteTransform(hTransform);
        cmsCloseProfile(hOutProfile);
        cmsCloseProfile(hInProfile);
    }
#endif

    png_destroy_read_struct(&png_ptr, &info_ptr, NULL);

    mainprog_ptr->file_size = read_data.bytes_read;
    mainprog_ptr->row_pointers = (unsigned char **)row_pointers;

    return SUCCESS;
}
コード例 #25
0
ファイル: Textures.cpp プロジェクト: Lundar/GUN
GLuint loadPNG(const char * file_name, GLuint tex)
{
    png_byte header[8];

    FILE *fp = fopen(file_name, "rb");
    if (fp == 0)
    {
        perror(file_name);
        return 0;
    }

    // read the header
    fread(header, 1, 8, fp);

    if (png_sig_cmp(header, 0, 8))
    {
        fprintf(stderr, "error: %s is not a PNG.\n", file_name);
        fclose(fp);
        return 0;
    }

    png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    if (!png_ptr)
    {
        fprintf(stderr, "error: png_create_read_struct returned 0.\n");
        fclose(fp);
        return 0;
    }

    // create png info struct
    png_infop info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr)
    {
        fprintf(stderr, "error: png_create_info_struct returned 0.\n");
        png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
        fclose(fp);
        return 0;
    }

    // create png info struct
    png_infop end_info = png_create_info_struct(png_ptr);
    if (!end_info)
    {
        fprintf(stderr, "error: png_create_info_struct returned 0.\n");
        png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL);
        fclose(fp);
        return 0;
    }

    // the code in this if statement gets called if libpng encounters an error
    if (setjmp(png_jmpbuf(png_ptr))) {
        fprintf(stderr, "error from libpng\n");
        png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
        fclose(fp);
        return 0;
    }

    // init png reading
    png_init_io(png_ptr, fp);

    // let libpng know you already read the first 8 bytes
    png_set_sig_bytes(png_ptr, 8);

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

    // variables to pass to get info
    int bit_depth, color_type;
    png_uint_32 temp_width, temp_height;

    // get info about png
    png_get_IHDR(png_ptr, info_ptr, &temp_width, &temp_height, &bit_depth, &color_type,
        NULL, NULL, NULL);

    GLint format;
    switch(color_type)
    {
    case PNG_COLOR_TYPE_RGB:
        format = GL_RGB;
        break;
    case PNG_COLOR_TYPE_RGB_ALPHA:
        format = GL_RGBA;
        break;
    case PNG_COLOR_TYPE_GRAY:
        //cout<<"color Type Grey"<<endl;
        format = GL_RGBA;
        png_set_gray_to_rgb(png_ptr);
        png_set_filler(png_ptr, 0xFF, PNG_FILLER_AFTER);

        break;
    case PNG_COLOR_TYPE_GRAY_ALPHA:
        //cout<<"color Type Grey Alpha"<<endl;
        format = GL_RGBA;
        png_set_gray_to_rgb(png_ptr);

        break;
    case PNG_COLOR_TYPE_PALETTE:
        //cout<<"color Type Palette"<<endl;
        format = GL_RGBA;
        png_set_palette_to_rgb(png_ptr);
        png_set_filler(png_ptr, 0xFF, PNG_FILLER_AFTER);
        //return 0;
        break;
    default:
        fprintf(stderr, "%s: Unknown libpng color type %d.\n", file_name, color_type);
        return 0;
    }

    // Update the png info struct.
    png_read_update_info(png_ptr, info_ptr);

    // Row size in bytes.
    int rowbytes = png_get_rowbytes(png_ptr, info_ptr);

    // glTexImage2d requires rows to be 4-byte aligned
    rowbytes += 3 - ((rowbytes-1) % 4);

    // Allocate the image_data as a big block, to be given to opengl
    png_byte * image_data;
    //image_data = (png_byte*) malloc(rowbytes * temp_height * sizeof(png_byte)+15);
    image_data = new png_byte[rowbytes * temp_height];
    if (image_data == NULL)
    {
        fprintf(stderr, "error: could not allocate memory for PNG image data\n");
        png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
        fclose(fp);
        return 0;
    }

    // row_pointers is for pointing to image_data for reading the png with libpng
    //png_bytep * row_pointers = (png_bytep*) malloc(temp_height * sizeof(png_bytep));
    png_bytep * row_pointers = new png_bytep[temp_height];
    if (row_pointers == NULL)
    {
        fprintf(stderr, "error: could not allocate memory for PNG row pointers\n");
        png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
        free(image_data);
        fclose(fp);
        return 0;
    }

    // set the individual row_pointers to point at the correct offsets of image_data
    int i;
    for (i = 0; i < temp_height; i++)
    {
        row_pointers[/*temp_height - 1 - */i] = image_data + i * rowbytes;
    }

    // read the png into image_data through row_pointers
    png_read_image(png_ptr, row_pointers);

    glBindTexture(GL_TEXTURE_2D, tex);

    glTexImage2D(GL_TEXTURE_2D, 0, format, temp_width, temp_height, 0, format, GL_UNSIGNED_BYTE, image_data);

    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    // clean up
    png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
    delete[] image_data;
    delete[] row_pointers;
    fclose(fp);
    return tex;
}
コード例 #26
0
bool BitmapData::initWithPNGData(const unsigned char *data, ssize_t size) {
    
    static const int PNGSIGSIZE = 8;
    
    png_byte        header[PNGSIGSIZE] = {0};
    png_structp     png_ptr     = 0;
    png_infop       info_ptr    = 0;
    
    memcpy(header, data, PNGSIGSIZE);
    if (png_sig_cmp(header, 0, PNGSIGSIZE) != 0) {
        return false;
    }
    
    png_ptr  = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
    info_ptr = png_create_info_struct(png_ptr);
    setjmp(png_jmpbuf(png_ptr));
    
    
    PngSource pngSource;
    pngSource.data    = (unsigned char*)data;
    pngSource.size    = size;
    pngSource.offset  = 0;
    png_set_read_fn(png_ptr, &pngSource, pngReadCallback);
    
    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_byte bit_depth = png_get_bit_depth(png_ptr, info_ptr);
    png_uint_32 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) {
        bit_depth = 8;
    }
    if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
        png_set_tRNS_to_alpha(png_ptr);
    }
    if (bit_depth == 16) {
        png_set_strip_16(png_ptr);
    }
    if (bit_depth < 8) {
        png_set_packing(png_ptr);
    }
    // update info
    png_read_update_info(png_ptr, info_ptr);
    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:
            _renderFormat = Texture2D::PixelFormat::I8;
            break;
        case PNG_COLOR_TYPE_GRAY_ALPHA:
            _renderFormat = Texture2D::PixelFormat::AI88;
            break;
        case PNG_COLOR_TYPE_RGB:
            _renderFormat = Texture2D::PixelFormat::RGB888;
            break;
        case PNG_COLOR_TYPE_RGB_ALPHA:
            _renderFormat = Texture2D::PixelFormat::RGBA8888;
            break;
        default:
            break;
    }
    
    // read png data
    png_size_t rowbytes;
    png_bytep* row_pointers = (png_bytep*)malloc(sizeof(png_bytep) * _height);
    rowbytes = png_get_rowbytes(png_ptr, info_ptr);
    
    _dataSize = rowbytes * _height;
    _data = static_cast<unsigned char*>(malloc(_dataSize * sizeof(unsigned char)));
    
    if(!_data) {
        if (row_pointers != nullptr) {
            free(row_pointers);
        }
        return false;
    }
    
    for (unsigned short i = 0; i < _height; ++i) {
        row_pointers[i] = _data + i*rowbytes;
    }
    
    png_read_image(png_ptr, row_pointers);
    png_read_end(png_ptr, nullptr);
    
    if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
        _alpha = true;
    } else {
        _alpha = false;
    }
    
    if (row_pointers != nullptr) {
        free(row_pointers);
    }
    
    if (png_ptr) {
        png_destroy_read_struct(&png_ptr, (info_ptr) ? &info_ptr : 0, 0);
    }
    
    return true;
}
コード例 #27
0
ファイル: R9ImgLoader.cpp プロジェクト: leprosarium/prolozzy
bool R9_ImgReadPNG( F9FILE file, r9Img* img )
{
	if(file==NULL || img==NULL) return false;
	R9_ImgDestroy(img);
	
	// check png sig
	const int headersize = 8;
	byte header[headersize];
	if(file->Read( header, headersize) != headersize) return false;

	BOOL ispng = png_check_sig(header, headersize) != 0;
	if(!ispng) { elog::rnd() << "png sig failed" << std::endl; return false; }

	// create png structures
	png_structp png_ptr = png_create_read_struct_2( PNG_LIBPNG_VER_STRING,
												NULL,
												R9_ImgPNG_FatalError,
												R9_ImgPNG_Warning,
												NULL,
												R9_ImgPNG_Malloc,
												R9_ImgPNG_Free );

	if(png_ptr==NULL) return false;

	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;
	}

	png_infop end_info = png_create_info_struct(png_ptr);
	if(end_info == NULL) 
	{
		png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
		return false;
	}

	// set global file
	r9_imgpng_file = file;
	png_set_read_fn(png_ptr, NULL, R9_ImgPNG_ReadData);

	// read off the info on the image
	png_set_sig_bytes(png_ptr, headersize);
	png_read_info(png_ptr, info_ptr);

	png_uint_32 pngwidth;
	png_uint_32 pngheight;	
	int32 pngbits;
	int32 pngpf;

	png_get_IHDR(png_ptr, info_ptr,
				&pngwidth, &pngheight,
				&pngbits, &pngpf,
				NULL,                        // interlace
				NULL,                        // compression_type
				NULL);                       // filter_type

	BOOL alpha = FALSE;
	img->m_width = pngwidth;
	img->m_height = pngheight;
	img->m_pf = R9_PF_RGB;
	assert(img->m_width!=0 && img->m_height!=0);

	// Strip off any 16 bit info
	if(pngbits==16) png_set_strip_16(png_ptr);

	// Expand a transparency channel into a full alpha channel...
	if(png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) 
	{
		png_set_expand(png_ptr);
		alpha = TRUE;
	}

	if( pngpf == PNG_COLOR_TYPE_RGB) 
	{
		png_set_expand(png_ptr);
		img->m_pf = alpha ? R9_PF_ARGB : R9_PF_RGB;
	} 
	else 
	if( pngpf == PNG_COLOR_TYPE_RGB_ALPHA) 
	{
		png_set_expand(png_ptr);
		img->m_pf = R9_PF_ARGB;
	}
	else
	{
		elog::rnd() << "png wrong color format" << std::endl;
		png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
		return false;
	}

	// Update the info pointer with the result of the transformations above...
	png_read_update_info(png_ptr, info_ptr);

	png_uint_32 rowbytes = png_get_rowbytes(png_ptr, info_ptr);
	if(img->m_pf==R9_PF_RGB) assert(rowbytes==img->m_width*3);
	else
	if(img->m_pf==R9_PF_RGB) assert(rowbytes==img->m_width*4);

	// create image
	R9_ImgCreate(img);

	// set up the row pointers...
	png_bytep* rowpointers = new png_bytep[img->m_height];
	for(int i=0; i<img->m_height; i++)
	  rowpointers[i] = img->m_data + (i*rowbytes);

	// read image
	png_read_image(png_ptr, rowpointers);

	// release
	png_read_end(png_ptr, NULL);
	png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
	delete [] rowpointers;
	r9_imgpng_file = NULL;

	R9_ImgFlipRGB(img); // it was BGR, we want it RGB !
	return true;
}
コード例 #28
0
/*
 * http://www.piko3d.com/tutorials/libpng-tutorial-loading-png-files-from-streams
 */
static unsigned char *readPNG(const char *filename) {
	unsigned char *buf;
	FILE *fp;
	png_byte magic[8];
	png_structp png_ptr;
	png_infop info_ptr;
	int bit_depth;
	int color_type;
	png_bytep *row_ptr;
	// int row_bytes;
	int i;

	if((fp = fopen(filename, "rb")) == NULL) {
		fprintf(stderr, "ERROR: readPng(): fopen %s\n", filename);
		return NULL;
	}

	/* check if the file is a .PNG */
	fread(magic, 1, sizeof(magic), fp);
	if(png_sig_cmp(magic, 0, sizeof(magic))) {
		printf("ERROR: readPNG(): %s is not a .png\n", filename);
		fclose(fp);
		return NULL;
	}

	png_ptr = png_create_read_struct(
		PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
	if(!png_ptr) {
		printf("ERROR: readPNG(): png_create_read_struct\n");
		fclose(fp);
		return NULL;
	}

	info_ptr = png_create_info_struct(png_ptr);
	if(!info_ptr) {
		printf("ERROR: readPNG(): png_create_info_struct\n");
		png_destroy_read_struct(&png_ptr, NULL, NULL);
		fclose(fp);
		return NULL;
	}

	if(setjmp(png_jmpbuf(png_ptr))) {
		printf("ERROR: readPNG(): setjmp\n");
		png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
		fclose(fp);
		return NULL;
	}

	/* read PNG info */
	png_init_io(png_ptr, fp);
	png_set_sig_bytes(png_ptr, sizeof(magic));

	png_read_info(png_ptr, info_ptr);

	tex_width = png_get_image_width(png_ptr, info_ptr);
	tex_height = png_get_image_height(png_ptr, info_ptr);
	color_type = png_get_color_type(png_ptr, info_ptr);
	bit_depth = png_get_bit_depth(png_ptr, info_ptr);

	/* convert to RGBA */
	if(color_type == PNG_COLOR_TYPE_PALETTE)
		png_set_palette_to_rgb(png_ptr);

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

	/* background to alpha */
	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);
	// row_bytes = png_get_rowbytes(png_ptr, info_ptr);

	buf = (unsigned char*)malloc(tex_width * tex_height * 4);
	row_ptr = (png_bytep*)malloc(sizeof(png_bytep) * tex_height);

	/* pointer indexes */
	for(i=0; i<tex_height; i++) {
		row_ptr[i] = (png_bytep)(buf + i * tex_width * 4);
	}	
	png_read_image(png_ptr, row_ptr);

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

	fclose(fp);

	return buf;	
}
コード例 #29
0
void RGBAUtilities::readPngFile(char* file_name)
{
    char header[8];    // 8 is the maximum size that can be checked
    
    /* open file and test for it being a png */
    FILE *fp = fopen(file_name, "rb");
    if (!fp)
        abort_("[read_png_file] File %s could not be opened for reading", file_name);
    fread(header, 1, 8, fp);
//    if (png_sig_cmp(header, 0, 8))
//        abort_("[read_png_file] File %s is not recognized as a PNG file", file_name);
//    
    
    /* initialize stuff */
    pngPtr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    
    if (!pngPtr)
        abort_("[read_png_file] png_create_read_struct failed");
    
    infoPtr = png_create_info_struct(pngPtr);
    if (!infoPtr)
        abort_("[read_png_file] png_create_info_struct failed");
    
    if (setjmp(png_jmpbuf(pngPtr)))
        abort_("[read_png_file] Error during init_io");
    
    png_init_io(pngPtr, fp);
    png_set_sig_bytes(pngPtr, 8);
    
    png_read_info(pngPtr, infoPtr);
    
    imageWidth = png_get_image_width(pngPtr, infoPtr);
    imageLength = png_get_image_height(pngPtr, infoPtr);
    config = png_get_color_type(pngPtr, infoPtr);
    bitsPerSample = png_get_bit_depth(pngPtr, infoPtr); // = 8 bits
        
    numberOfPasses = png_set_interlace_handling(pngPtr);
    png_read_update_info(pngPtr, infoPtr);
    
    imageWidth = png_get_image_width(pngPtr, infoPtr);
    imageLength = png_get_image_height(pngPtr, infoPtr);

    samplesPerPixel = png_get_channels(pngPtr, infoPtr); // = 4 bytes

    bitsPerPixel = samplesPerPixel*bitsPerSample;
    linebytes = samplesPerPixel * imageWidth; // = 640
    //linebytes = png_get_rowbytes(pngPtr, infoPtr); = 640
    imageBitSize = (sizeof(uint8) * imageWidth * imageLength * samplesPerPixel);
    imageSize = imageWidth * imageLength * samplesPerPixel;
    //printf("linebytes = %i, expected %i\n",linebytes,png_get_rowbytes(pngPtr, infoPtr));
    //printf("Image Height is %d", sizeof(png_bytep) * imageLength);

    
    /* read file */
    if (setjmp(png_jmpbuf(pngPtr)))
        abort_("[read_png_file] Error during read_image");
    
    rowPointers = (png_bytep*) malloc(sizeof(png_bytep) * imageLength);
    for (y=0; y<imageLength; y++)
        rowPointers[y] = (png_byte*) malloc(png_get_rowbytes(pngPtr,infoPtr));
    
    png_read_image(pngPtr, rowPointers);
    
    fclose(fp);
}
コード例 #30
0
static void
gst_pngdec_task (GstPad * pad)
{
  GstPngDec *pngdec;
  GstBuffer *buffer = NULL;
  size_t buffer_size = 0;
  gint i = 0;
  png_bytep *rows, inp;
  png_uint_32 rowbytes;
  GstFlowReturn ret = GST_FLOW_OK;

  pngdec = GST_PNGDEC (GST_OBJECT_PARENT (pad));

  GST_LOG_OBJECT (pngdec, "read frame");

  /* Let libpng come back here on error */
  if (setjmp (png_jmpbuf (pngdec->png))) {
    ret = GST_FLOW_ERROR;
    goto pause;
  }

  /* Set reading callback */
  png_set_read_fn (pngdec->png, pngdec, user_read_data);

  /* Read info */
  png_read_info (pngdec->png, pngdec->info);

  /* Generate the caps and configure */
  ret = gst_pngdec_caps_create_and_set (pngdec);
  if (ret != GST_FLOW_OK) {
    goto pause;
  }

  /* Allocate output buffer */
  rowbytes = png_get_rowbytes (pngdec->png, pngdec->info);
  buffer_size = pngdec->height * GST_ROUND_UP_4 (rowbytes);
  ret =
      gst_pad_alloc_buffer_and_set_caps (pngdec->srcpad, GST_BUFFER_OFFSET_NONE,
      buffer_size, GST_PAD_CAPS (pngdec->srcpad), &buffer);
  if (ret != GST_FLOW_OK) {
    goto pause;
  }

  rows = (png_bytep *) g_malloc (sizeof (png_bytep) * pngdec->height);

  inp = GST_BUFFER_DATA (buffer);

  for (i = 0; i < pngdec->height; i++) {
    rows[i] = inp;
    inp += GST_ROUND_UP_4 (rowbytes);
  }

  /* Read the actual picture */
  png_read_image (pngdec->png, rows);
  free (rows);

  /* Push the raw RGB frame */
  ret = gst_pad_push (pngdec->srcpad, buffer);
  if (ret != GST_FLOW_OK) {
    goto pause;
  }

  /* And we are done */
  gst_pad_pause_task (pngdec->sinkpad);
  gst_pad_push_event (pngdec->srcpad, gst_event_new_eos ());
  return;

pause:
  GST_INFO_OBJECT (pngdec, "pausing task, reason %s", gst_flow_get_name (ret));
  gst_pad_pause_task (pngdec->sinkpad);
  if (GST_FLOW_IS_FATAL (ret) || ret == GST_FLOW_NOT_LINKED) {
    GST_ELEMENT_ERROR (pngdec, STREAM, FAILED,
        (_("Internal data stream error.")),
        ("stream stopped, reason %s", gst_flow_get_name (ret)));
    gst_pad_push_event (pngdec->srcpad, gst_event_new_eos ());
  }
}