Пример #1
0
ImBuf *IMB_ibImageFromMemory(unsigned char *mem, size_t size, int flags)
{
	ImBuf *ibuf;
	ImFileType *type;

	if(mem == NULL) {
		printf("Error in ibImageFromMemory: NULL pointer\n");
		return NULL;
	}

	for(type=IMB_FILE_TYPES; type->is_a; type++) {
		if(type->load) {
			ibuf= type->load(mem, size, flags);
			if(ibuf) {
				if(flags & IB_premul) {
					IMB_premultiply_alpha(ibuf);
					ibuf->flags |= IB_premul;
				}

				return ibuf;
			}
		}
	}

	fprintf(stderr, "Unknown fileformat\n");
	
	return NULL;
}
Пример #2
0
/** Handle deferred (lazy) loading/generation of preview image, if needed.
 * For now, only used with file thumbnails. */
void BKE_previewimg_ensure(PreviewImage *prv, const int size)
{
	if (prv->use_deferred) {
		const bool do_icon = ((size == ICON_SIZE_ICON) && !prv->rect[ICON_SIZE_ICON]);
		const bool do_preview = ((size == ICON_SIZE_PREVIEW) && !prv->rect[ICON_SIZE_PREVIEW]);

		if (do_icon || do_preview) {
			ImBuf *thumb;
			char *prv_deferred_data = PRV_DEFERRED_DATA(prv);
			int source =  prv_deferred_data[0];
			char *path = &prv_deferred_data[1];
			int icon_w, icon_h;

			thumb = IMB_thumb_manage(path, THB_LARGE, source);

			if (thumb) {
				/* PreviewImage assumes premultiplied alhpa... */
				IMB_premultiply_alpha(thumb);

				if (do_preview) {
					prv->w[ICON_SIZE_PREVIEW] = thumb->x;
					prv->h[ICON_SIZE_PREVIEW] = thumb->y;
					prv->rect[ICON_SIZE_PREVIEW] = MEM_dupallocN(thumb->rect);
					prv->flag[ICON_SIZE_PREVIEW] &= ~(PRV_CHANGED | PRV_USER_EDITED);
				}
				if (do_icon) {
					if (thumb->x > thumb->y) {
						icon_w = ICON_RENDER_DEFAULT_HEIGHT;
						icon_h = (thumb->y * icon_w) / thumb->x + 1;
					}
					else if (thumb->x < thumb->y) {
						icon_h = ICON_RENDER_DEFAULT_HEIGHT;
						icon_w = (thumb->x * icon_h) / thumb->y + 1;
					}
					else {
						icon_w = icon_h = ICON_RENDER_DEFAULT_HEIGHT;
					}

					IMB_scaleImBuf(thumb, icon_w, icon_h);
					prv->w[ICON_SIZE_ICON] = icon_w;
					prv->h[ICON_SIZE_ICON] = icon_h;
					prv->rect[ICON_SIZE_ICON] = MEM_dupallocN(thumb->rect);
					prv->flag[ICON_SIZE_ICON] &= ~(PRV_CHANGED | PRV_USER_EDITED);
				}
				IMB_freeImBuf(thumb);
			}
		}
	}
}
Пример #3
0
static void imb_handle_alpha(ImBuf *ibuf, int flags, char colorspace[IM_MAX_SPACE], char effective_colorspace[IM_MAX_SPACE])
{
	int alpha_flags;

	if (colorspace) {
		if (ibuf->rect) {
			/* byte buffer is never internally converted to some standard space,
			 * store pointer to it's color space descriptor instead
			 */
			ibuf->rect_colorspace = colormanage_colorspace_get_named(effective_colorspace);
		}

		BLI_strncpy(colorspace, effective_colorspace, IM_MAX_SPACE);
	}

	if (flags & IB_alphamode_detect)
		alpha_flags = ibuf->flags & IB_alphamode_premul;
	else
		alpha_flags = flags & IB_alphamode_premul;

	if (flags & IB_ignore_alpha) {
		IMB_rectfill_alpha(ibuf, 1.0f);
	}
	else {
		if (alpha_flags & IB_alphamode_premul) {
			if (ibuf->rect) {
				IMB_unpremultiply_alpha(ibuf);
			}
			else {
				/* pass, floats are expected to be premul */
			}
		}
		else {
			if (ibuf->rect_float) {
				IMB_premultiply_alpha(ibuf);
			}
			else {
				/* pass, bytes are expected to be straight */
			}
		}
	}

	/* OCIO_TODO: in some cases it's faster to do threaded conversion,
	 *            but how to distinguish such cases */
	colormanage_imbuf_make_linear(ibuf, effective_colorspace);
}
Пример #4
0
static void init_internal_icons(void)
{
//	bTheme *btheme = UI_GetTheme();
	ImBuf *b16buf = NULL, *b32buf = NULL;
	int x, y, icontype;

#if 0 // temp disabled
	if ((btheme != NULL) && btheme->tui.iconfile[0]) {
		char *icondir = BKE_appdir_folder_id(BLENDER_DATAFILES, "icons");
		char iconfilestr[FILE_MAX];
		
		if (icondir) {
			BLI_join_dirfile(iconfilestr, sizeof(iconfilestr), icondir, btheme->tui.iconfile);
			bbuf = IMB_loadiffname(iconfilestr, IB_rect, NULL); /* if the image is missing bbuf will just be NULL */
			if (bbuf && (bbuf->x < ICON_IMAGE_W || bbuf->y < ICON_IMAGE_H)) {
				printf("\n***WARNING***\nIcons file %s too small.\nUsing built-in Icons instead\n", iconfilestr);
				IMB_freeImBuf(bbuf);
				bbuf = NULL;
			}
		}
		else {
			printf("%s: 'icons' data path not found, continuing\n", __func__);
		}
	}
#endif
	if (b16buf == NULL)
		b16buf = IMB_ibImageFromMemory((unsigned char *)datatoc_blender_icons16_png,
		                               datatoc_blender_icons16_png_size, IB_rect, NULL, "<blender icons>");
	if (b16buf)
		IMB_premultiply_alpha(b16buf);

	if (b32buf == NULL)
		b32buf = IMB_ibImageFromMemory((unsigned char *)datatoc_blender_icons32_png,
		                               datatoc_blender_icons32_png_size, IB_rect, NULL, "<blender icons>");
	if (b32buf)
		IMB_premultiply_alpha(b32buf);
	
	if (b16buf && b32buf) {
		/* free existing texture if any */
		if (icongltex.id) {
			glDeleteTextures(1, &icongltex.id);
			icongltex.id = 0;
		}

		/* we only use a texture for cards with non-power of two */
		if (GPU_non_power_of_two_support()) {
			glGenTextures(1, &icongltex.id);

			if (icongltex.id) {
				int level = 2;
				
				icongltex.w = b32buf->x;
				icongltex.h = b32buf->y;
				icongltex.invw = 1.0f / b32buf->x;
				icongltex.invh = 1.0f / b32buf->y;

				glBindTexture(GL_TEXTURE_2D, icongltex.id);
				
				glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, b32buf->x, b32buf->y, 0, GL_RGBA, GL_UNSIGNED_BYTE, b32buf->rect);
				glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, b16buf->x, b16buf->y, 0, GL_RGBA, GL_UNSIGNED_BYTE, b16buf->rect);
				
				while (b16buf->x > 1) {
					ImBuf *nbuf = IMB_onehalf(b16buf);
					glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, nbuf->x, nbuf->y, 0, GL_RGBA, GL_UNSIGNED_BYTE, nbuf->rect);
					level++;
					IMB_freeImBuf(b16buf);
					b16buf = nbuf;
				}
				
				glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
				glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
				
				glBindTexture(GL_TEXTURE_2D, 0);
				
				if (glGetError() == GL_OUT_OF_MEMORY) {
					glDeleteTextures(1, &icongltex.id);
					icongltex.id = 0;
				}
			}
		}
	}

	if (icongltex.id)
		icontype = ICON_TYPE_TEXTURE;
	else
		icontype = ICON_TYPE_BUFFER;
	
	if (b32buf) {
		for (y = 0; y < ICON_GRID_ROWS; y++) {
			for (x = 0; x < ICON_GRID_COLS; x++) {
				def_internal_icon(b32buf, BIFICONID_FIRST + y * ICON_GRID_COLS + x,
				                  x * (ICON_GRID_W + ICON_GRID_MARGIN) + ICON_GRID_MARGIN,
				                  y * (ICON_GRID_H + ICON_GRID_MARGIN) + ICON_GRID_MARGIN, ICON_GRID_W,
				                  icontype);
			}
		}
	}

	def_internal_vicon(VICO_VIEW3D_VEC, vicon_view3d_draw);
	def_internal_vicon(VICO_EDIT_VEC, vicon_edit_draw);
	def_internal_vicon(VICO_EDITMODE_VEC_DEHLT, vicon_editmode_dehlt_draw);
	def_internal_vicon(VICO_EDITMODE_VEC_HLT, vicon_editmode_hlt_draw);
	def_internal_vicon(VICO_DISCLOSURE_TRI_RIGHT_VEC, vicon_disclosure_tri_right_draw);
	def_internal_vicon(VICO_DISCLOSURE_TRI_DOWN_VEC, vicon_disclosure_tri_down_draw);
	def_internal_vicon(VICO_MOVE_UP_VEC, vicon_move_up_draw);
	def_internal_vicon(VICO_MOVE_DOWN_VEC, vicon_move_down_draw);
	def_internal_vicon(VICO_X_VEC, vicon_x_draw);
	def_internal_vicon(VICO_SMALL_TRI_RIGHT_VEC, vicon_small_tri_right_draw);

	IMB_freeImBuf(b16buf);
	IMB_freeImBuf(b32buf);
	
}
Пример #5
0
static void icon_preview_startjob(void *customdata, short *stop, short *do_update)
{
	ShaderPreview *sp = customdata;

	if (sp->pr_method == PR_ICON_DEFERRED) {
		PreviewImage *prv = sp->owner;
		ImBuf *thumb;
		char *deferred_data = PRV_DEFERRED_DATA(prv);
		int source =  deferred_data[0];
		char *path = &deferred_data[1];

//		printf("generating deferred %d×%d preview for %s\n", sp->sizex, sp->sizey, path);

		thumb = IMB_thumb_manage(path, THB_LARGE, source);

		if (thumb) {
			/* PreviewImage assumes premultiplied alhpa... */
			IMB_premultiply_alpha(thumb);

			icon_copy_rect(thumb, sp->sizex, sp->sizey, sp->pr_rect);
			IMB_freeImBuf(thumb);
		}
	}
	else {
		ID *id = sp->id;
		short idtype = GS(id->name);

		if (idtype == ID_IM) {
			Image *ima = (Image *)id;
			ImBuf *ibuf = NULL;
			ImageUser iuser = {NULL};

			/* ima->ok is zero when Image cannot load */
			if (ima == NULL || ima->ok == 0)
				return;

			/* setup dummy image user */
			iuser.ok = iuser.framenr = 1;
			iuser.scene = sp->scene;

			/* elubie: this needs to be changed: here image is always loaded if not
			 * already there. Very expensive for large images. Need to find a way to
			 * only get existing ibuf */
			ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL);
			if (ibuf == NULL || ibuf->rect == NULL) {
				BKE_image_release_ibuf(ima, ibuf, NULL);
				return;
			}

			icon_copy_rect(ibuf, sp->sizex, sp->sizey, sp->pr_rect);

			*do_update = true;

			BKE_image_release_ibuf(ima, ibuf, NULL);
		}
		else if (idtype == ID_BR) {
			Brush *br = (Brush *)id;

			br->icon_imbuf = get_brush_icon(br);

			memset(sp->pr_rect, 0x88, sp->sizex * sp->sizey * sizeof(unsigned int));

			if (!(br->icon_imbuf) || !(br->icon_imbuf->rect))
				return;

			icon_copy_rect(br->icon_imbuf, sp->sizex, sp->sizey, sp->pr_rect);

			*do_update = true;
		}
		else {
			/* re-use shader job */
			shader_preview_startjob(customdata, stop, do_update);

			/* world is rendered with alpha=0, so it wasn't displayed
			 * this could be render option for sky to, for later */
			if (idtype == ID_WO) {
				set_alpha((char *)sp->pr_rect, sp->sizex, sp->sizey, 255);
			}
			else if (idtype == ID_MA) {
				Material *ma = (Material *)id;

				if (ma->material_type == MA_TYPE_HALO)
					set_alpha((char *)sp->pr_rect, sp->sizex, sp->sizey, 255);
			}
		}
	}
}
Пример #6
0
/* 
 * Use the libTIFF scanline API to read a TIFF image.
 * This method is most flexible and can handle multiple different bit depths 
 * and RGB channel orderings.
 */
static int imb_read_tiff_pixels(ImBuf *ibuf, TIFF *image, int premul)
{
	ImBuf *tmpibuf;
	int success= 0;
	short bitspersample, spp, config;
	size_t scanline;
	int ib_flag=0, row, chan;
	float *fbuf=NULL;
	unsigned short *sbuf=NULL;

	TIFFGetField(image, TIFFTAG_BITSPERSAMPLE, &bitspersample);
	TIFFGetField(image, TIFFTAG_SAMPLESPERPIXEL, &spp);		/* number of 'channels' */
	TIFFGetField(image, TIFFTAG_PLANARCONFIG, &config);

	imb_read_tiff_resolution(ibuf, image);

	scanline = TIFFScanlineSize(image);
	
	if (bitspersample == 32) {
		ib_flag = IB_rectfloat;
		fbuf = (float *)_TIFFmalloc(scanline);
	}
	else if (bitspersample == 16) {
		ib_flag = IB_rectfloat;
		sbuf = (unsigned short *)_TIFFmalloc(scanline);
	}
	else {
		ib_flag = IB_rect;
	}
	
	tmpibuf= IMB_allocImBuf(ibuf->x, ibuf->y, ibuf->planes, ib_flag);
	
	/* simple RGBA image */
	if (!(bitspersample == 32 || bitspersample == 16)) {
		success |= TIFFReadRGBAImage(image, ibuf->x, ibuf->y, tmpibuf->rect, 0);
	}
	/* contiguous channels: RGBRGBRGB */
	else if (config == PLANARCONFIG_CONTIG) {
		for (row = 0; row < ibuf->y; row++) {
			int ib_offset = ibuf->x*ibuf->y*4 - ibuf->x*4 * (row+1);
		
			if (bitspersample == 32) {
				success |= TIFFReadScanline(image, fbuf, row, 0);
				scanline_contig_32bit(tmpibuf->rect_float+ib_offset, fbuf, ibuf->x, spp);
				
			}
			else if (bitspersample == 16) {
				success |= TIFFReadScanline(image, sbuf, row, 0);
				scanline_contig_16bit(tmpibuf->rect_float+ib_offset, sbuf, ibuf->x, spp);
			}
		}
	/* separate channels: RRRGGGBBB */
	}
	else if (config == PLANARCONFIG_SEPARATE) {
		
		/* imbufs always have 4 channels of data, so we iterate over all of them
		 * but only fill in from the TIFF scanline where necessary. */
		for (chan = 0; chan < 4; chan++) {
			for (row = 0; row < ibuf->y; row++) {
				int ib_offset = ibuf->x*ibuf->y*4 - ibuf->x*4 * (row+1);
				
				if (bitspersample == 32) {
					if (chan == 3 && spp == 3) /* fill alpha if only RGB TIFF */
						fill_vn_fl(fbuf, ibuf->x, 1.0f);
					else if (chan >= spp) /* for grayscale, duplicate first channel into G and B */
						success |= TIFFReadScanline(image, fbuf, row, 0);
					else
						success |= TIFFReadScanline(image, fbuf, row, chan);
					scanline_separate_32bit(tmpibuf->rect_float+ib_offset, fbuf, ibuf->x, chan);
					
				}
				else if (bitspersample == 16) {
					if (chan == 3 && spp == 3) /* fill alpha if only RGB TIFF */
						fill_vn_ushort(sbuf, ibuf->x, 65535);
					else if (chan >= spp) /* for grayscale, duplicate first channel into G and B */
						success |= TIFFReadScanline(image, fbuf, row, 0);
					else
						success |= TIFFReadScanline(image, sbuf, row, chan);
					scanline_separate_16bit(tmpibuf->rect_float+ib_offset, sbuf, ibuf->x, chan);
					
				}
			}
		}
	}
	
	if (bitspersample == 32)
		_TIFFfree(fbuf);
	else if (bitspersample == 16)
		_TIFFfree(sbuf);

	if (success) {
		ibuf->profile = (bitspersample==32)?IB_PROFILE_LINEAR_RGB:IB_PROFILE_SRGB;

//		Code seems to be not needed for 16 bits tif, on PPC G5 OSX (ton)
		if (bitspersample < 16)
			if (ENDIAN_ORDER == B_ENDIAN)
				IMB_convert_rgba_to_abgr(tmpibuf);
		if (premul) {
			IMB_premultiply_alpha(tmpibuf);
			ibuf->flags |= IB_premul;
		}
		
		/* assign rect last */
		if (tmpibuf->rect_float)
			ibuf->rect_float= tmpibuf->rect_float;
		else	
			ibuf->rect= tmpibuf->rect;
		ibuf->mall |= ib_flag;
		ibuf->flags |= ib_flag;
		
		tmpibuf->mall &= ~ib_flag;
	}

	IMB_freeImBuf(tmpibuf);
	
	return success;
}