Пример #1
0
static void *load_tga(FILE *fp, int *xsz, int *ysz)
{
	struct tga_header hdr;
	unsigned long x, y, sz;
	int i;
	uint32_t *pix, ppixel = 0;
	int rle_mode = 0, rle_pix_left = 0;
	int rdalpha;

	/* read header */
	fseek(fp, 0, SEEK_SET);
	hdr.idlen = fgetc(fp);
	hdr.cmap_type = fgetc(fp);
	hdr.img_type = fgetc(fp);
	hdr.cmap_first = read_int16_le(fp);
	hdr.cmap_len = read_int16_le(fp);
	hdr.cmap_entry_sz = fgetc(fp);
	hdr.img_x = read_int16_le(fp);
	hdr.img_y = read_int16_le(fp);
	hdr.img_width = read_int16_le(fp);
	hdr.img_height = read_int16_le(fp);
	hdr.img_bpp = fgetc(fp);
	hdr.img_desc = fgetc(fp);

	if(feof(fp)) {
		return 0;
	}

	/* only read true color images */
	if(!IS_RGBA(hdr.img_type)) {
		fprintf(stderr, "only true color tga images supported\n");
		return 0;
	}

	fseek(fp, hdr.idlen, SEEK_CUR); /* skip the image ID */

	/* skip the color map if it exists */
	if(hdr.cmap_type == 1) {
		fseek(fp, hdr.cmap_len * hdr.cmap_entry_sz / 8, SEEK_CUR);
	}

	x = hdr.img_width;
	y = hdr.img_height;
	sz = x * y;
	if(!(pix = malloc(sz * 4))) {
		return 0;
	}

	rdalpha = hdr.img_desc & 0xf;

	for(i=0; i<y; i++) {
		uint32_t *ptr;
		int j;

		ptr = pix + ((hdr.img_desc & 0x20) ? i : y-(i+1)) * x;

		for(j=0; j<x; j++) {
			/* if the image is raw, then just read the next pixel */
			if(!IS_RLE(hdr.img_type)) {
				ppixel = read_pixel(fp, rdalpha);
			} else {
                /* otherwise, for RLE... */

				/* if we have pixels left in the packet ... */
				if(rle_pix_left) {
					/* if it's a raw packet, read the next pixel, otherwise keep the same */
					if(!rle_mode) {
						ppixel = read_pixel(fp, rdalpha);
					}
					rle_pix_left--;
				} else {
					/* read the RLE packet header */
					unsigned char packet_hdr = getc(fp);
					rle_mode = (packet_hdr & 128);		/* last bit shows the mode for this packet (1: rle, 0: raw) */
					rle_pix_left = (packet_hdr & ~128);	/* the rest gives the count of pixels minus one (we also read one here, so no +1) */
					ppixel = read_pixel(fp, rdalpha);	/* and read the first pixel of the packet */
				}
			}

			*ptr++ = ppixel;

			if(feof(fp)) break;
		}
	}

	*xsz = x;
	*ysz = y;

	return pix;
}
Пример #2
0
void *load_tga(FILE *fp, unsigned long *xsz, unsigned long *ysz) {
	struct tga_header hdr;
	unsigned long x, y, sz;
	int i;
	uint32_t *pix;

	/* read header */
	fseek(fp, 0, SEEK_SET);
	hdr.idlen = fgetc(fp);
	hdr.cmap_type = fgetc(fp);
	hdr.img_type = fgetc(fp);
	hdr.cmap_first = read_int16_le(fp);
	hdr.cmap_len = read_int16_le(fp);
	hdr.cmap_entry_sz = fgetc(fp);
	hdr.img_x = read_int16_le(fp);
	hdr.img_y = read_int16_le(fp);
	hdr.img_width = read_int16_le(fp);
	hdr.img_height = read_int16_le(fp);
	hdr.img_bpp = fgetc(fp);
	hdr.img_desc = fgetc(fp);

	if(feof(fp)) {
		fclose(fp);
		return 0;
	}
	
	/* only read true color images */
	if(hdr.img_type != 2) {
		fclose(fp);
		fprintf(stderr, "only true color tga images supported\n");
		return 0;
	}

	fseek(fp, hdr.idlen, SEEK_CUR); /* skip the image ID */

	/* skip the color map if it exists */
	if(hdr.cmap_type == 1) {
		fseek(fp, hdr.cmap_len * hdr.cmap_entry_sz / 8, SEEK_CUR);
	}

	x = hdr.img_width;
	y = hdr.img_height;
	sz = x * y;
	if(!(pix = malloc(sz * 4))) {
		fclose(fp);
		return 0;
	}

	for(i=0; i<y; i++) {
		uint32_t *ptr;
		int j;

		ptr = pix + ((hdr.img_desc & 0x20) ? i : y-(i+1)) * x;

		for(j=0; j<x; j++) {
			unsigned char r, g, b, a;
			r = fgetc(fp);
			g = fgetc(fp);
			b = fgetc(fp);
			a = (hdr.img_desc & 0xf) ? fgetc(fp) : 255;
		
			*ptr++ = PACK_COLOR32(a, r, g, b);
			
			if(feof(fp)) break;
		}
	}

	fclose(fp);
	*xsz = x;
	*ysz = y;
	return pix;
}