示例#1
0
void imb_loadtiletiff(ImBuf *ibuf, unsigned char *mem, size_t size, int tx, int ty, unsigned int *rect)
{
	TIFF *image = NULL;
	uint32 width, height;
	ImbTIFFMemFile memFile;

	image = imb_tiff_client_open(&memFile, mem, size);

	if(image == NULL) {
		printf("imb_loadtiff: could not open TIFF IO layer for loading mipmap level.\n");
		return;
	}

   	if(TIFFSetDirectory(image, ibuf->miplevel)) {
		/* allocate the image buffer */
		TIFFGetField(image, TIFFTAG_IMAGEWIDTH,  &width);
		TIFFGetField(image, TIFFTAG_IMAGELENGTH, &height);

		if(width == ibuf->x && height == ibuf->y) {
			if(rect) {
				/* tiff pixels are bottom to top, tiles are top to bottom */
				if(TIFFReadRGBATile(image, tx*ibuf->tilex, (ibuf->ytiles - 1 - ty)*ibuf->tiley, rect) == 1) {
					if(ibuf->tiley > ibuf->y)
						memmove(rect, rect+ibuf->tilex*(ibuf->tiley - ibuf->y), sizeof(int)*ibuf->tilex*ibuf->y);

					if(ibuf->flags & IB_premul)
						IMB_premultiply_rect(rect, 32, ibuf->tilex, ibuf->tiley);
				}
				else
					printf("imb_loadtiff: failed to read tiff tile at mipmap level %d\n", ibuf->miplevel);
			}
		}
		else
			printf("imb_loadtiff: mipmap level %d has unexpected size %dx%d instead of %dx%d\n", ibuf->miplevel, width, height, ibuf->x, ibuf->y);
	}
	else
		printf("imb_loadtiff: could not find mipmap level %d\n", ibuf->miplevel);

	/* close the client layer interface to the in-memory file */
	TIFFClose(image);
}
示例#2
0
/**
 * Loads a TIFF file.
 *
 *
 * \param mem:   Memory containing the TIFF file.
 * \param size:  Size of the mem buffer.
 * \param flags: If flags has IB_test set then the file is not actually loaded,
 *                but all other operations take place.
 *
 * \return: A newly allocated ImBuf structure if successful, otherwise NULL.
 */
ImBuf *imb_loadtiff(unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE])
{
	TIFF *image = NULL;
	ImBuf *ibuf = NULL, *hbuf;
	ImbTIFFMemFile memFile;
	uint32 width, height;
	char *format = NULL;
	int level;
	short spp;
	int ib_depth;

	/* check whether or not we have a TIFF file */
	if (size < IMB_TIFF_NCB) {
		fprintf(stderr, "imb_loadtiff: size < IMB_TIFF_NCB\n");
		return NULL;
	}
	if (imb_is_a_tiff(mem) == 0)
		return NULL;

	/* both 8 and 16 bit PNGs are default to standard byte colorspace */
	colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE);

	image = imb_tiff_client_open(&memFile, mem, size);

	if (image == NULL) {
		printf("imb_loadtiff: could not open TIFF IO layer.\n");
		return NULL;
	}

	/* allocate the image buffer */
	TIFFGetField(image, TIFFTAG_IMAGEWIDTH,  &width);
	TIFFGetField(image, TIFFTAG_IMAGELENGTH, &height);
	TIFFGetField(image, TIFFTAG_SAMPLESPERPIXEL, &spp);
	
	ib_depth = (spp == 3) ? 24 : 32;
	
	ibuf = IMB_allocImBuf(width, height, ib_depth, 0);
	if (ibuf) {
		ibuf->ftype = TIF;
	}
	else {
		fprintf(stderr, 
		        "imb_loadtiff: could not allocate memory for TIFF "
		        "image.\n");
		TIFFClose(image);
		return NULL;
	}

	/* get alpha mode from file header */
	if (flags & IB_alphamode_detect) {
		if (spp == 4) {
			unsigned short extra, *extraSampleTypes;

			TIFFGetField(image, TIFFTAG_EXTRASAMPLES, &extra, &extraSampleTypes);

			if (extraSampleTypes[0] == EXTRASAMPLE_ASSOCALPHA)
				ibuf->flags |= IB_alphamode_premul;
		}
	}

	/* if testing, we're done */
	if (flags & IB_test) {
		TIFFClose(image);
		return ibuf;
	}

	/* detect if we are reading a tiled/mipmapped texture, in that case
	 * we don't read pixels but leave it to the cache to load tiles */
	if (flags & IB_tilecache) {
		format = NULL;
		TIFFGetField(image, TIFFTAG_PIXAR_TEXTUREFORMAT, &format);

		if (format && strcmp(format, "Plain Texture") == 0 && TIFFIsTiled(image)) {
			int numlevel = TIFFNumberOfDirectories(image);

			/* create empty mipmap levels in advance */
			for (level = 0; level < numlevel; level++) {
				if (!TIFFSetDirectory(image, level))
					break;

				if (level > 0) {
					width = (width > 1) ? width / 2 : 1;
					height = (height > 1) ? height / 2 : 1;

					hbuf = IMB_allocImBuf(width, height, 32, 0);
					hbuf->miplevel = level;
					hbuf->ftype = ibuf->ftype;
					ibuf->mipmap[level - 1] = hbuf;
				}
				else
					hbuf = ibuf;

				hbuf->flags |= IB_tilecache;

				TIFFGetField(image, TIFFTAG_TILEWIDTH, &hbuf->tilex);
				TIFFGetField(image, TIFFTAG_TILELENGTH, &hbuf->tiley);

				hbuf->xtiles = ceil(hbuf->x / (float)hbuf->tilex);
				hbuf->ytiles = ceil(hbuf->y / (float)hbuf->tiley);

				imb_addtilesImBuf(hbuf);

				ibuf->miptot++;
			}
		}
	}

	/* read pixels */
	if (!(ibuf->flags & IB_tilecache) && !imb_read_tiff_pixels(ibuf, image)) {
		fprintf(stderr, "imb_loadtiff: Failed to read tiff image.\n");
		TIFFClose(image);
		return NULL;
	}

	/* close the client layer interface to the in-memory file */
	TIFFClose(image);

	/* return successfully */
	return ibuf;
}