Example #1
0
int int_png_load(const char *name, unsigned char **buffer, int* xp, int* yp, int* bpp, bool alpha)
{
	static const png_color_16 my_background = {0, 0, 0, 0, 0};
	png_structp png_ptr;
	png_infop info_ptr;
	png_uint_32 width, height;
	unsigned int i;
	int bit_depth, color_type, interlace_type, number_passes, pass, int_bpp;
	png_byte * fbptr;
	FILE     * fh;

	if(!(fh=fopen(name,"rb")))
		return(FH_ERROR_FILE);
	png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
	if(png_ptr == NULL) {
		fclose(fh);
		return(FH_ERROR_FORMAT);
	}
	info_ptr = png_create_info_struct(png_ptr);
	if(info_ptr == NULL)
	{
		png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
		fclose(fh);
		return(FH_ERROR_FORMAT);
	}
#if (PNG_LIBPNG_VER < 10500)
	if (setjmp(png_ptr->jmpbuf))
#else
	if (setjmp(png_jmpbuf(png_ptr)))
#endif
	{
		png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
		fclose(fh);
		return(FH_ERROR_FORMAT);
	}
	png_init_io(png_ptr,fh);
	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 (alpha)
	{
		*bpp = png_get_channels(png_ptr, info_ptr);
		if ((*bpp != 4) || !(color_type & PNG_COLOR_MASK_ALPHA))
		{
			png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
			fclose(fh);
			return fh_png_load(name, buffer, xp, yp);
		}
		// 24bit PNGs with alpha-channel
		int_bpp = 4;
//		png_set_swap_alpha(png_ptr);
		if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
			png_set_tRNS_to_alpha(png_ptr);
	}else // All other PNGs
	{
		if (color_type == PNG_COLOR_TYPE_PALETTE)
		{
			png_set_palette_to_rgb(png_ptr);
			png_set_background(png_ptr, (png_color_16*)&my_background, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
			/* other possibility for png_set_background: use png_get_bKGD */
		}
		if (color_type == PNG_COLOR_TYPE_GRAY        ||
		    color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
		{
			png_set_gray_to_rgb(png_ptr);
			png_set_background(png_ptr, (png_color_16*)&my_background, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
		}
		/* this test does not trigger for 8bit-paletted PNGs with newer libpng (1.2.36 at least),
	   	   but the data delivered is with alpha channel anyway, so always strip alpha for now
		 */
#if PNG_LIBPNG_VER_MAJOR == 1 && PNG_LIBPNG_VER_MINOR <= 2 && PNG_LIBPNG_VER_RELEASE < 36
		if (color_type & PNG_COLOR_MASK_ALPHA)
#endif
			png_set_strip_alpha(png_ptr);
		if (bit_depth < 8)
			png_set_packing(png_ptr);
		int_bpp = 3;
	}
	if (bit_depth == 16)
		png_set_strip_16(png_ptr);
	number_passes = png_set_interlace_handling(png_ptr);
	png_read_update_info(png_ptr,info_ptr);
	unsigned long rowbytes = png_get_rowbytes(png_ptr, info_ptr);
	if (width * int_bpp != rowbytes)
	{
		printf("[png.cpp]: Error processing %s - please report (including image).\n", name);
		printf("           width: %lu rowbytes: %lu\n", (unsigned long)width, (unsigned long)rowbytes);
		fclose(fh);
		return(FH_ERROR_FORMAT);
	}
	for (pass = 0; pass < number_passes; pass++)
	{
		fbptr = (png_byte *)(*buffer);
		for (i = 0; i < height; i++, fbptr += width * int_bpp)
			png_read_row(png_ptr, fbptr, NULL);
	}
	png_read_end(png_ptr, info_ptr);
	png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
	fclose(fh);
	return(FH_ERROR_OK);
}
Example #2
0
File: main.c Project: kaihs/fbvs
int show_image(char *devicename)
{

	unsigned char * image = NULL;
	unsigned char * alpha = NULL;

	int x_size, y_size, screen_width, screen_height;
	int x_pan, y_pan, x_offs, y_offs, refresh = 1, ret = 1;
	int retransform = 1;

	int transform_stretch = opt_stretch, transform_enlarge = opt_enlarge, transform_cal = (opt_stretch == 2),
	    transform_iaspect = opt_ignore_aspect, transform_rotation = 0;

	struct image i;
	
	memset(&i,0, sizeof(i));

	if(fh_png_load(&image, &alpha, &x_size, &y_size) != FH_ERROR_OK) {
		fprintf(stderr, "Image data is corrupt?\n");
		goto error_mem;
	}

	if(!opt_alpha) {
		free(alpha);
		alpha = NULL;
	}



	getCurrentRes(devicename, &screen_width, &screen_height);
	i.do_free = 0;
	if(retransform) {
		if(i.do_free) {
			free(i.rgb);
			free(i.alpha);
		}
		i.width = x_size;
		i.height = y_size;
		i.rgb = image;
		i.alpha = alpha;
		i.do_free = 0;


		if(transform_rotation)
			do_rotate(&i, transform_rotation);

		if(transform_stretch)
			do_fit_to_screen(&i, screen_width, screen_height, transform_iaspect, transform_cal);

		if(transform_enlarge)
			do_enlarge(&i, screen_width, screen_height, transform_iaspect);

		x_pan = y_pan = 0;
		refresh = 1;
		retransform = 0;
	}
	if(refresh) {
		if(i.width < screen_width)
			x_offs = (screen_width - i.width) / 2;
		else
			x_offs = 0;

		if(i.height < screen_height)
			y_offs = (screen_height - i.height) / 2;
		else
			y_offs = 0;

		fb_display(devicename, i.rgb, i.alpha, i.width, i.height, x_pan, y_pan, x_offs, y_offs);
		refresh = 0;
	}



error_mem:
	free(image);
	free(alpha);
	if(i.do_free) {
		free(i.rgb);
		free(i.alpha);
	}
	return(ret);

}