Loading textures from PNG (or other image formats)

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
Ess
Posts: 16
Joined: Thu Apr 20, 2006 8:16 am

Loading textures from PNG (or other image formats)

Post by Ess »

How do I load a texture from an image file (other than RAW, and preferably PNG).

Could someone give me a complete (or at least a few lines as to how to do this?

Any help is greatly apreciated.
subbie
Posts: 122
Joined: Thu May 05, 2005 4:14 am

Post by subbie »

could always read up on TGA loading from nehe.gamedev.net
AnonymousTipster
Posts: 197
Joined: Fri Jul 01, 2005 2:50 am

Post by AnonymousTipster »

May your wish be granted:

Code: Select all

static unsigned int vramaddr = 0;

unsigned char *loadPNGfromfile(const char *filename,int widp, int heip, int swizzleit)
{
  //this function loads into RAM, not VRAM
	//u32* vram32;
	//u16* vram16;
	//int bufferwidth;
	//int pixelformat;
	//int unknown;
	png_structp png_ptr;
	png_infop info_ptr;
	unsigned int sig_read = 0;
	png_uint_32 width, height;
	int bit_depth, color_type, interlace_type, x, y;
	u32* line;
	FILE *fp;
	int wid, hei;
	//wid = RoundUpPow2(widp);
	//hei = RoundUpPow2(heip);
	int maxWid, maxHei

	//load the PNG
	if ((fp = fopen(filename, "rb")) == NULL) return NULL;
	png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
	if (png_ptr == NULL) {
		fclose(fp);
		return NULL;
	}
	png_set_error_fn(png_ptr, (png_voidp) NULL, (png_error_ptr) 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);
		return NULL;
	}
	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);
	wid = RoundUpPow2(width);
	hei = RoundUpPow2(height);
	//widp = 10; 
	//heip = 10; 
	maxWid = getMaxInt(wid,(int)width);
	maxHei = getMaxInt(hei,(int)height);
	png_set_strip_16(png_ptr);
	png_set_packing(png_ptr);
	if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png_ptr);
	if &#40;color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8&#41; png_set_gray_1_2_4_to_8&#40;png_ptr&#41;;
	if &#40;png_get_valid&#40;png_ptr, info_ptr, PNG_INFO_tRNS&#41;&#41; png_set_tRNS_to_alpha&#40;png_ptr&#41;;
	png_set_filler&#40;png_ptr, 0xff, PNG_FILLER_AFTER&#41;;
	line = &#40;u32*&#41;memalign&#40;16,RoundUpPow2&#40;width&#41; * 4&#41;;
	if &#40;!line&#41; &#123;
		fclose&#40;fp&#41;;
		png_destroy_read_struct&#40;&png_ptr, png_infopp_NULL, png_infopp_NULL&#41;;
		return NULL;
	&#125;

  int c;
  x=0;
  y=0;	
  //unsigned char *input = inptr;
  unsigned char __attribute__&#40;&#40;aligned&#40;16&#41;&#41;&#41; *output;
  unsigned char __attribute__&#40;&#40;aligned&#40;16&#41;&#41;&#41; *outptr;
  //unsigned char *output2, *outptr2;
  size_t sizediff;
  sizediff = maxWid*maxHei*4;
  //if &#40;ramaddr == 0&#41;
    //ramaddr = &#40;unsigned int&#41;malloc&#40;sizediff&#41;;//&#40;0x40000000 | 0x04000000&#41; + VRAM_OFFSET;
  c=0;
  ramaddr = &#40;unsigned int&#41;memalign&#40;16,sizediff&#41;;
  outptr = output = &#40;unsigned char *&#41;ramaddr;
  outptr = output;
  for &#40;y=0;y<maxHei;y++&#41; &#123;
	  if&#40;y < height&#41;&#123;
		  png_read_row&#40;png_ptr, &#40;u8*&#41; line, png_bytep_NULL&#41;;//&#125;else&#123;
		  //line = NULL;&#125;
  for &#40;x=0;x<maxWid;x++&#41;&#123;
	  int r = 0xff; 
	  int g = 0xff; 
	  int b = 0xff;
	  int a = 0x00;
	  //if&#40;x < maxWid-width || y < maxHei-height&#41;&#123;a = 0x00;&#125;
	  
	  if&#40;x <= width  && y <= height&#41;&#123;
	  
			u32 color32 = line&#91;x&#93;;
			r = color32 & 0xff; 
			g = &#40;color32 >> 8&#41; & 0xff;
			b = &#40;color32 >> 16&#41; & 0xff;
			a = &#40;color32 >> 24&#41; & 0xff;
			&#125;
		outptr&#91;&#40;int&#41;&#40;&#40;x*4&#41;+&#40;y*maxWid*4&#41;&#41;&#93; = r;
		outptr&#91;&#40;int&#41;&#40;&#40;x*4&#41;+&#40;y*maxWid*4&#41;+1&#41;&#93; = g;
		outptr&#91;&#40;int&#41;&#40;&#40;x*4&#41;+&#40;y*maxWid*4&#41;+2&#41;&#93; = b;
		outptr&#91;&#40;int&#41;&#40;&#40;x*4&#41;+&#40;y*maxWid*4&#41;+3&#41;&#93; = a;
  &#125;
  &#125;else&#123;for &#40;x=0;x<maxWid;x++&#41;&#123;outptr&#91;&#40;int&#41;&#40;&#40;x*4&#41;+&#40;y*maxWid*4&#41;+3&#41;&#93; = 0;&#125;&#125;

  &#125;

  fclose&#40;fp&#41;;

  if&#40;swizzleit == 0&#41;&#123;
  return output; 
  &#125;else&#123;
  //return output;
  unsigned char __attribute__&#40;&#40;aligned&#40;16&#41;&#41;&#41;*swizzled;
  swizzled = &#40;unsigned char*&#41;memalign&#40;16,maxWid*maxHei*4&#41;;
	swizzle&#40;swizzled,output,maxWid,maxHei&#41;;
	//free old texture
	free&#40;output&#41;;
	return swizzled;
  &#125;
&#125;

//swizzles the texture &#40;only use with static textures, else too slow&#41;
void swizzle&#40;u8* out, const u8* in, unsigned int width, unsigned int height&#41;
&#123;
	//note this function is modified to take into account that 1 pixel &#40;32bit&#41; is
	//actually 4 u8, so if you don't want this, change width*4 to width
   unsigned int i,j;
   unsigned int rowblocks = &#40;&#40;width*4&#41; / 16&#41;;
 
   for &#40;j = 0; j < height; ++j&#41;
   &#123;
      for &#40;i = 0; i < &#40;width*4&#41;; ++i&#41;
      &#123;
         unsigned int blockx = i / 16;
         unsigned int blocky = j / 8;
 
         unsigned int x = &#40;i - blockx*16&#41;;
         unsigned int y = &#40;j - blocky*8&#41;;
         unsigned int block_index = blockx + &#40;&#40;blocky&#41; * rowblocks&#41;;
         unsigned int block_address = block_index * 16 * 8;
 
         out&#91;block_address + x + y * 16&#93; = in&#91;i+j*&#40;width*4&#41;&#93;;
      &#125;
   &#125;
&#125;
Note that this function pads to power of 2, so if your texture is 200x100, the texture ends up 256x128.
Ess
Posts: 16
Joined: Thu Apr 20, 2006 8:16 am

Post by Ess »

Wow, thank you.

What libraries do I need to include?
Gary13579
Posts: 93
Joined: Mon Aug 15, 2005 7:43 am

Post by Gary13579 »

libpng for sure, and likely zlib.
Ess
Posts: 16
Joined: Thu Apr 20, 2006 8:16 am

Post by Ess »

Ok. Is there any way to simplify that using loadImage();
soulphalanx
Posts: 35
Joined: Mon Aug 22, 2005 7:48 am

Post by soulphalanx »

just use graphics.h from luaplayer source
Post Reply