Esempio n. 1
0
img_t *img_parse_tga(int len, const char *data, lua_State *L)
{
	// TODO: make this routine safer
	// it's possible to crash this in a whole bunch of ways

	const char *p = data;
	const char *dend = data+len;
	int x,y,i;
	img_tgahead_t head;

	// read header
	assert((unsigned long)len >= (unsigned long)sizeof(img_tgahead_t));
	//memcpy(&head, p, sizeof(img_tgahead_t));
	//p += sizeof(img_tgahead_t);
	// header has to be read semiproperly because gcc has no idea what packed means since 4.7
	memcpy(&head.idlen,   p +  0, 1);
	memcpy(&head.cmtype,  p +  1, 1);
	memcpy(&head.imgtype, p +  2, 1);
	memcpy(&head.cmoffs,  p +  3, 2);
	memcpy(&head.cmlen,   p +  5, 2);
	memcpy(&head.cmbpp,   p +  7, 1);
	memcpy(&head.xstart,  p +  8, 2);
	memcpy(&head.ystart,  p + 10, 2);
	memcpy(&head.width,   p + 12, 2);
	memcpy(&head.height,  p + 14, 2);
	memcpy(&head.bpp,     p + 16, 1);
	memcpy(&head.flags,   p + 17, 1);
	p += 18;

	int bplen = ((head.bpp-1)>>3)+1;
	assert((unsigned long)len >= (unsigned long)(sizeof(img_tgahead_t) + head.idlen));

	// skip ID field
	p += head.idlen;

	// jump to palette

	// load palette if necessary
	uint32_t *palette = (head.cmtype == 1 ? (uint32_t*)malloc(head.cmlen*4) : NULL);

	if(palette != NULL)
	{
		int tclen = ((head.cmbpp-1)>>3)+1;
		assert((unsigned long)len >= (unsigned long)(sizeof(img_tgahead_t) + head.idlen
			+ head.cmlen*tclen));

		memset(palette, 0, 4*head.cmlen);
		for(i = 0; i < head.cmlen; i++)
		{
			// TODO check what happens when the offset is different
			uint32_t tmp_col = 0;
			memcpy(&tmp_col, p, tclen);
			p += tclen;
			palette[i] = img_convert_color_to_32(tmp_col, head.cmbpp);
			//printf("%6i %08X\n", i, palette[i]);
		}
	}
Esempio n. 2
0
img_t *img_parse_tga(int len, const char *data)
{
	// TODO: make this routine safer
	// it's possible to crash this in a whole bunch of ways
	
	const char *p = data;
	const char *dend = data+len;
	int x,y,i;
	img_tgahead_t head;
	
	// read header
	memcpy(&head, p, sizeof(img_tgahead_t));
	p += sizeof(img_tgahead_t);
	
	// skip ID field
	p += head.idlen;
	
	// jump to palette
	
	// load palette if necessary
	uint32_t *palette = (head.cmtype == 1 ? (uint32_t*)malloc(head.cmlen*4) : NULL);
	
	if(palette != NULL)
	for(i = 0; i < head.cmlen; i++)
	{
		// TODO check what happens when the offset is different
		uint32_t tmp_col;
		int tclen = ((head.cmbpp-1)>>3)+1;
		memcpy(&tmp_col, p, tclen);
		p += tclen;
		palette[i] = img_convert_color_to_32(tmp_col, head.cmbpp);
		//printf("%6i %08X\n", i, palette[i]);
	}
	
	// allocate + stash
	int iw, ih;
	iw = head.width;
	ih = head.height;
#ifdef USE_OPENGL
	expandtex_gl(&iw, &ih);
#endif
	printf("TEX: %i %i\n", iw, ih);
	img_t *img = (img_t*)malloc(sizeof(img_t)+4*iw*ih);
	// TODO: check if NULL
	img->head = head;
	img->udtype = UD_IMG;
#ifdef USE_OPENGL
	img->tex = 0;
	img->tex_dirty = 1;
#endif
	
	// copy stuff
	int bplen = ((head.bpp-1)>>3)+1;
	int idx = (head.flags & 32 ? 0 : head.height-1)*iw;
	for(y = 0; y < head.height; y++)
	{
		if(head.imgtype & 8)
		{
			// RLE
			x = 0;
			uint32_t tmp_col;
			while(x < head.width)
			{
				int rle = (int)(uint8_t)(*p++);
				if(rle & 0x80)
				{
					rle &= 0x7F;
					
					memcpy(&tmp_col, p, bplen);
					p += bplen;
					
					for(i = 0; i <= rle && x < head.width && p < dend; i++, x++)
						img->pixels[idx++] = tmp_col;
				} else {
					for(i = 0; i <= rle && x < head.width && p < dend; i++, x++)
					{
						memcpy(&tmp_col, p, bplen);
						p += bplen;
						
						img->pixels[idx++] = tmp_col;
					}
				}
			}
		} else {
			// raw
			uint32_t tmp_col;
			for(x = 0; x < head.width && p < dend; x++)
			{
				memcpy(&tmp_col, p, bplen);
				p += bplen;
				img->pixels[idx++] = tmp_col;
			}
		}
		
		idx += iw-head.width;
		if(!(head.flags & 32))
			idx -= 2*iw;
	}
	
	// convert pixels
	if((head.imgtype&7) == 1)
	{
		for(i = iw*ih-1; i >= 0; i--)
			img->pixels[i] = palette[(img->pixels[i] + head.cmoffs) % head.cmlen];
		//printf("cm %i %i\n", head.cmoffs, head.cmlen);
	} else {
		for(i = iw*ih-1; i >= 0; i--)
			img->pixels[i] = img_convert_color_to_32(img->pixels[i], head.bpp);
	}
	
	// free palette
	free(palette);
	
	// now return!
	return img;
}