Esempio n. 1
0
image_t *gfx_display_acquire(gfx_display_t *gfxd, void **pHandle)
{
    if (gfxd)
    {
        uint32_t idx = 0;
        if (bitfield_get(&gfxd->used, &idx))
        {
            uint8_t *bufs[4] = {0,0,0,0};
            int ret = 0;
            int usage = GRALLOC_USAGE_HW_TEXTURE |
                        GRALLOC_USAGE_HW_RENDER |
                        GRALLOC_USAGE_SW_READ_RARELY |
                        GRALLOC_USAGE_SW_WRITE_NEVER;

            // save the handle with the client
            *pHandle = (void *)gfxd->handles[idx];

            // allocate an image structure,
            gfxd->images[idx] = image_allocate(gfxd->width, gfxd->height, gfxd->color);

            // by locking the memory we are mapping it to our UVA
            ret = gfxd->module->base.lock((const struct gralloc_module_t *)gfxd->module, (buffer_handle_t)gfxd->handles[idx], usage, 0, 0, gfxd->width, gfxd->height, (void **)bufs);

            DVP_PRINT(DVP_ZONE_VIDEO, "Locking %p to {%p, %p, %p, %p} (ret=%d)\n", gfxd->handles[idx], bufs[0], bufs[1], bufs[2], bufs[3], ret);

            // fill in the details in the image_t structure...
            if (gfxd->color == FOURCC_NV12) {
                gfxd->images[idx]->plane[0].ptr = bufs[0];
                gfxd->images[idx]->plane[1].ptr = bufs[1];
                gfxd->images[idx]->plane[0].ystride = gfxd->stride;
                gfxd->images[idx]->plane[1].ystride = gfxd->stride;
            } else {
                gfxd->images[idx]->plane[0].ptr = bufs[0];
                gfxd->images[idx]->plane[0].ystride = gfxd->stride;
            }
            return gfxd->images[idx];
        }
    }
    return NULL;
}
Esempio n. 2
0
image_t*
image_initf(uint32 width, uint32 height, PIXEL_FORMAT fmt, void* initial_state, image_initf_fun_t filler) {
	void*		state	= initial_state;
	image_t*	img	= image_allocate(width, height, fmt);
	uint32		pixel_size	= 0;
	uint8*		data	= (uint8*)img->pixels;
	pixel_setf_fun_t	fun	= NULL;

	switch(fmt) {
	case PF_A8:			pixel_size	= 1; fun	= set_pixelf_a8;		break;
	case PF_R8G8B8:		pixel_size	= 3; fun	= set_pixelf_r8g8b8;	break;
	case PF_R8G8B8A8:	pixel_size	= 4; fun	= set_pixelf_r8g8b8a8;	break;
	}

	for( uint32 y = 0; y < height; ++y ) {
		for( uint32 x = 0; x < width; ++x ) {
			uint32		offset	= (x + y * width) * pixel_size;
			color4_t	col	= filler(state, x, y);
			fun(&data[offset], col);
		}
	}

	return img;
}
Esempio n. 3
0
image_t*
image_load_png(const char* path) {
	png_structp		png_ptr;
	png_infop		info_ptr;
	unsigned int	sig_read	= 0;
	int				color_type, interlace_type;
	FILE*			fp;
	png_uint_32		width, height;
	int				bit_depth;
	unsigned int	row_bytes;
	PIXEL_FORMAT	sf			= PF_A8;
	uint32			pixel_size	= 0;
	uint32			width_size	= 0;
	image_t*		tex			= NULL;
	char*			buff		= NULL;
	png_bytepp		row_pointers;
	uint32			r;	/* row */

	if( (fp = fopen(path, "rb")) == NULL ) {
		fprintf(stderr, "ERROR: load_png: %s not found\n", path);
		return NULL;
	}

	/* Create and initialize the png_struct
	* with the desired error handler
	* functions. If you want to use the
	* default stderr and longjump method,
	* you can supply NULL for the last
	* three parameters. We also supply the
	* the compiler header file version, so
	* that we know if the application
	* was compiled with a compatible version
	* of the library. REQUIRED
	*/
	png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
	if( png_ptr == NULL ) {
		fclose(fp);

		fprintf(stderr, "ERROR: load_png: %s: invalid PNG format\n", path);
	}

	/* Allocate/initialize the memory
	* for image information. REQUIRED. */
	info_ptr = png_create_info_struct(png_ptr);
	if (info_ptr == NULL) {
		fclose(fp);
		png_destroy_read_struct(&png_ptr, NULL, NULL);

		fprintf(stderr, "ERROR: load_png: %s: not enough memory or format not supported\n", path);
		return NULL;
	}

	/* Set error handling if you are
	* using the setjmp/longjmp method
	* (this is the normal method of
	* doing things with libpng).
	* REQUIRED unless you set up
	* your own error handlers in
	* the png_create_read_struct()
	* earlier.
	*/
	if (setjmp(png_jmpbuf(png_ptr))) {
		/* Free all of the memory associated
			* with the png_ptr and info_ptr */
		png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
		fclose(fp);
		/* If we get here, we had a
			* problem reading the file */
		fprintf(stderr, "ERROR: load_png: inconsistant file %s\n", path);
		return NULL;
	}

	/* Set up the output control if
	* you are using standard C streams */
	png_init_io(png_ptr, fp);
	/* If we have already
	* read some of the signature */
	png_set_sig_bytes(png_ptr, sig_read);
	/*
	* If you have enough memory to read
	* in the entire image at once, and
	* you need to specify only
	* transforms that can be controlled
	* with one of the PNG_TRANSFORM_*
	* bits (this presently excludes
	* dithering, filling, setting
	* background, and doing gamma
	* adjustment), then you can read the
	* entire image (including pixels)
	* into the info structure with this
	* call
	*
	* PNG_TRANSFORM_STRIP_16 |
	* PNG_TRANSFORM_PACKING forces 8 bit
	* PNG_TRANSFORM_EXPAND forces to
	* expand a palette into RGB
	*/
	png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_PACKING | PNG_TRANSFORM_EXPAND, NULL);

	png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, NULL, NULL);

	row_bytes = png_get_rowbytes(png_ptr, info_ptr);

	switch( color_type ) {
	case PNG_COLOR_TYPE_GRAY:
	case PNG_COLOR_TYPE_GRAY_ALPHA:
		sf	= PF_A8;
		pixel_size	= 1;
		break;
	case PNG_COLOR_TYPE_RGB:
		sf	= PF_R8G8B8;
		pixel_size	= 3;
		break;
	case PNG_COLOR_TYPE_RGB_ALPHA:
		sf	= PF_R8G8B8A8;
		pixel_size	= 4;
		break;
	}

	// align the opengl texture to 4 byte width
	width_size	= width * pixel_size;
	tex			= image_allocate(width, height, sf);

	if( !tex ) {
		/* Clean up after the read,
		* and free any memory allocated */
		png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
		/* Close the file */
		fclose(fp);

		return tex;
	}

	buff			= (char*)tex->pixels;
	row_pointers	= png_get_rows(png_ptr, info_ptr);

	for( r = 0; r < height; r++ ) {
		// note that png is ordered top to
		// bottom, but OpenGL expect it bottom to top
		// so the order or swapped
		memcpy(&(buff[width_size * r]), row_pointers[r], width_size);
	}

	/* Clean up after the read,
	* and free any memory allocated */
	png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
	/* Close the file */
	fclose(fp);

	return tex;
}
Esempio n. 4
0
atlas_t*
image_atlas_make(uint32 image_count, const image_t** images) {
	stbrp_rect*	rects	= NULL;
	stbrp_node*	nodes	= NULL;
	stbrp_context	ctx;
	uint32		r;
	uint32		best_size;
	image_t*	tex		= NULL;
	atlas_t*	atlas	= NULL;
	rect_t*		drects	= NULL;

	/* try to find the best texture size */
	best_size	= find_best_size(image_count, images);

	/* create the texture and fill in the pixels */
	tex	= image_allocate(best_size, best_size, PF_R8G8B8A8);
	assert( NULL != tex );

	/* image to rect */
	rects	= (stbrp_rect*)malloc(sizeof(stbrp_rect) * image_count);
	assert( NULL != rects );

	for( r = 0; r < image_count; ++r ) {
		rects[r]	= image_to_rect(r, images[r]);
	}

	/* nodes */
	nodes	= (stbrp_node*)malloc(sizeof(stbrp_node) * best_size * 2);
	assert( NULL != nodes );

	memset(nodes, 0, sizeof(stbrp_node) * best_size * 2);

	/* desitnation rectangles */
	drects	= (rect_t*)malloc(sizeof(rect_t) * image_count);
	assert( NULL != drects );

	memset(drects, 0, sizeof(rect_t) * image_count);

	/* pack */
	stbrp_init_target(&ctx, (int)best_size, (int)best_size, nodes, (int)best_size * 2);
	stbrp_pack_rects(&ctx, rects, (int)image_count);

	free(nodes);

	/* copy the rectangle */
	for( r = 0; r < image_count; ++r ) {
		uint32	y;
		uint32	h	= images[r]->height;
		uint32	w	= images[r]->width;

		assert( rects[r].was_packed );

		drects[r].x	= rects[r].x;
		drects[r].y	= rects[r].y;
		drects[r].width	= rects[r].w;
		drects[r].height= rects[r].h;

		for( y = 0; y < h ; ++y ) {
			uint32	x;
			for( x = 0; x < w; ++x ) {
				color4b_t	src	= image_get_pixelb(images[r], x, y);
				image_set_pixelb(tex, rects[r].x + x, rects[r].y + y, src);
			}
		}
	}

	/* release resources */
	free(rects);

	/* final result */
	atlas	= (atlas_t*)malloc(sizeof(atlas_t));
	assert( NULL != atlas );

	atlas->baked_image	= tex;
	atlas->coordinates	= drects;
	atlas->image_count	= image_count;
	return atlas;
}