Example #1
0
static void whiteBalance_apply(SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask)
{
	WhiteBalanceThreadData data;
	WhiteBalanceModifierData *wbmd = (WhiteBalanceModifierData *) smd;

	copy_v3_v3(data.white, wbmd->white_value);
	IMB_colormanagement_display_to_scene_linear_v3(data.white,
	                                               IMB_colormanagement_display_get_named(wbmd->modifier.scene->display_settings.display_device));
	data.colorspace = ibuf->rect_colorspace;

	modifier_apply_threaded(ibuf, mask, whiteBalance_apply_threaded, &data);
}
Example #2
0
void blf_draw_buffer__start(FontBLF *font)
{
	FontBufInfoBLF *buf_info = &font->buf_info;

	buf_info->col_char[0] = buf_info->col_init[0] * 255;
	buf_info->col_char[1] = buf_info->col_init[1] * 255;
	buf_info->col_char[2] = buf_info->col_init[2] * 255;
	buf_info->col_char[3] = buf_info->col_init[3] * 255;

	if (buf_info->display) {
		copy_v4_v4(buf_info->col_float, buf_info->col_init);
		IMB_colormanagement_display_to_scene_linear_v3(buf_info->col_float, buf_info->display);
	}
	else {
		srgb_to_linearrgb_v4(buf_info->col_float, buf_info->col_init);
	}
}
Example #3
0
/* sets the sample color RGB, maintaining A */
static void eyedropper_color_set(bContext *C, Eyedropper *eye, const float col[3])
{
	float col_conv[4];

	/* to maintain alpha */
	RNA_property_float_get_array(&eye->ptr, eye->prop, col_conv);

	/* convert from display space to linear rgb space */
	if (eye->display) {
		copy_v3_v3(col_conv, col);
		IMB_colormanagement_display_to_scene_linear_v3(col_conv, eye->display);
	}
	else {
		copy_v3_v3(col_conv, col);
	}

	RNA_property_float_set_array(&eye->ptr, eye->prop, col_conv);

	RNA_property_update(C, &eye->ptr, eye->prop);
}
Example #4
0
/* Sanity checks are done by BLF_draw_buffer() */
void blf_font_buffer(FontBLF *font, const char *str)
{
	unsigned int c;
	GlyphBLF *g, *g_prev = NULL;
	FT_Vector delta;
	int pen_x = (int)font->pos[0], pen_y = 0;
	size_t i = 0;
	GlyphBLF **glyph_ascii_table = font->glyph_cache->glyph_ascii_table;

	/* buffer specific vars */
	FontBufInfoBLF *buf_info = &font->buf_info;
	float b_col_float[4];
	const unsigned char b_col_char[4] = {
	    (unsigned char)(buf_info->col[0] * 255),
	    (unsigned char)(buf_info->col[1] * 255),
	    (unsigned char)(buf_info->col[2] * 255),
	    (unsigned char)(buf_info->col[3] * 255)};

	unsigned char *cbuf;
	int chx, chy;
	int y, x;
	float a, *fbuf;

	BLF_KERNING_VARS(font, has_kerning, kern_mode);

	blf_font_ensure_ascii_table(font);

	/* another buffer specific call for color conversion */
	if (buf_info->display) {
		copy_v4_v4(b_col_float, buf_info->col);
		IMB_colormanagement_display_to_scene_linear_v3(b_col_float, buf_info->display);
	}
	else {
		srgb_to_linearrgb_v4(b_col_float, buf_info->col);
	}

	while (str[i]) {
		BLF_UTF8_NEXT_FAST(font, g, str, i, c, glyph_ascii_table);

		if (UNLIKELY(c == BLI_UTF8_ERR))
			break;
		if (UNLIKELY(g == NULL))
			continue;
		if (has_kerning)
			BLF_KERNING_STEP(font, kern_mode, g_prev, g, delta, pen_x);

		chx = pen_x + ((int)g->pos_x);
		chy = (int)font->pos[1] + g->height;

		if (g->pitch < 0) {
			pen_y = (int)font->pos[1] + (g->height - (int)g->pos_y);
		}
		else {
			pen_y = (int)font->pos[1] - (g->height - (int)g->pos_y);
		}

		if ((chx + g->width) >= 0 && chx < buf_info->w && (pen_y + g->height) >= 0 && pen_y < buf_info->h) {
			/* don't draw beyond the buffer bounds */
			int width_clip = g->width;
			int height_clip = g->height;
			int yb_start = g->pitch < 0 ? 0 : g->height - 1;

			if (width_clip + chx > buf_info->w)
				width_clip -= chx + width_clip - buf_info->w;
			if (height_clip + pen_y > buf_info->h)
				height_clip -= pen_y + height_clip - buf_info->h;
			
			/* drawing below the image? */
			if (pen_y < 0) {
				yb_start += (g->pitch < 0) ? -pen_y : pen_y;
				height_clip += pen_y;
				pen_y = 0;
			}

			if (buf_info->fbuf) {
				int yb = yb_start;
				for (y = ((chy >= 0) ? 0 : -chy); y < height_clip; y++) {
					for (x = ((chx >= 0) ? 0 : -chx); x < width_clip; x++) {
						a = *(g->bitmap + x + (yb * g->pitch)) / 255.0f;

						if (a > 0.0f) {
							float alphatest;
							fbuf = buf_info->fbuf + buf_info->ch * ((chx + x) + ((pen_y + y) * buf_info->w));
							if (a >= 1.0f) {
								fbuf[0] = b_col_float[0];
								fbuf[1] = b_col_float[1];
								fbuf[2] = b_col_float[2];
								fbuf[3] = (alphatest = (fbuf[3] + (b_col_float[3]))) < 1.0f ? alphatest : 1.0f;
							}
							else {
								fbuf[0] = (b_col_float[0] * a) + (fbuf[0] * (1.0f - a));
								fbuf[1] = (b_col_float[1] * a) + (fbuf[1] * (1.0f - a));
								fbuf[2] = (b_col_float[2] * a) + (fbuf[2] * (1.0f - a));
								fbuf[3] = (alphatest = (fbuf[3] + (b_col_float[3] * a))) < 1.0f ? alphatest : 1.0f;
							}
						}
					}

					if (g->pitch < 0)
						yb++;
					else
						yb--;
				}
			}

			if (buf_info->cbuf) {
				int yb = yb_start;
				for (y = 0; y < height_clip; y++) {
					for (x = 0; x < width_clip; x++) {
						a = *(g->bitmap + x + (yb * g->pitch)) / 255.0f;

						if (a > 0.0f) {
							int alphatest;
							cbuf = buf_info->cbuf + buf_info->ch * ((chx + x) + ((pen_y + y) * buf_info->w));
							if (a >= 1.0f) {
								cbuf[0] = b_col_char[0];
								cbuf[1] = b_col_char[1];
								cbuf[2] = b_col_char[2];
								
								alphatest = (int)cbuf[3] + (int)b_col_char[3];
								if (alphatest < 255) {
									cbuf[3] = (unsigned char)(alphatest);
								}
								else {
									cbuf[3] = 255;
								}
							}
							else {
								cbuf[0] = (unsigned char)((b_col_char[0] * a) + (cbuf[0] * (1.0f - a)));
								cbuf[1] = (unsigned char)((b_col_char[1] * a) + (cbuf[1] * (1.0f - a)));
								cbuf[2] = (unsigned char)((b_col_char[2] * a) + (cbuf[2] * (1.0f - a)));
								
								alphatest = ((int)cbuf[3] + (int)((b_col_float[3] * a) * 255.0f));
								if (alphatest < 255) {
									cbuf[3] = (unsigned char)(alphatest);
								}
								else {
									cbuf[3] = 255;
								}
							}
						}
					}

					if (g->pitch < 0)
						yb++;
					else
						yb--;
				}
			}
		}

		pen_x += g->advance_i;
		g_prev = g;
	}
}
Example #5
0
void buf_rectfill_area(unsigned char *rect, float *rectf, int width, int height,
                       const float col[4], struct ColorManagedDisplay *display,
                       int x1, int y1, int x2, int y2)
{
	int i, j;
	float a; /* alpha */
	float ai; /* alpha inverted */
	float aich; /* alpha, inverted, ai/255.0 - Convert char to float at the same time */
	if ((!rect && !rectf) || (!col) || col[3] == 0.0f)
		return;
	
	/* sanity checks for coords */
	CLAMP(x1, 0, width);
	CLAMP(x2, 0, width);
	CLAMP(y1, 0, height);
	CLAMP(y2, 0, height);

	if (x1 > x2) SWAP(int, x1, x2);
	if (y1 > y2) SWAP(int, y1, y2);
	if (x1 == x2 || y1 == y2) return;
	
	a = col[3];
	ai = 1 - a;
	aich = ai / 255.0f;

	if (rect) {
		unsigned char *pixel; 
		unsigned char chr = 0, chg = 0, chb = 0;
		float fr = 0, fg = 0, fb = 0;

		const int alphaint = FTOCHAR(a);
		
		if (a == 1.0f) {
			chr = FTOCHAR(col[0]);
			chg = FTOCHAR(col[1]);
			chb = FTOCHAR(col[2]);
		}
		else {
			fr = col[0] * a;
			fg = col[1] * a;
			fb = col[2] * a;
		}
		for (j = 0; j < y2 - y1; j++) {
			for (i = 0; i < x2 - x1; i++) {
				pixel = rect + 4 * (((y1 + j) * width) + (x1 + i));
				if (pixel >= rect && pixel < rect + (4 * (width * height))) {
					if (a == 1.0f) {
						pixel[0] = chr;
						pixel[1] = chg;
						pixel[2] = chb;
						pixel[3] = 255;
					}
					else {
						int alphatest;
						pixel[0] = (char)((fr + ((float)pixel[0] * aich)) * 255.0f);
						pixel[1] = (char)((fg + ((float)pixel[1] * aich)) * 255.0f);
						pixel[2] = (char)((fb + ((float)pixel[2] * aich)) * 255.0f);
						pixel[3] = (char)((alphatest = ((int)pixel[3] + alphaint)) < 255 ? alphatest : 255);
					}
				}
			}
		}
	}
	
	if (rectf) {
		float col_conv[4];
		float *pixel;

		if (display) {
			copy_v4_v4(col_conv, col);
			IMB_colormanagement_display_to_scene_linear_v3(col_conv, display);
		}
		else {
			srgb_to_linearrgb_v4(col_conv, col);
		}

		for (j = 0; j < y2 - y1; j++) {
			for (i = 0; i < x2 - x1; i++) {
				pixel = rectf + 4 * (((y1 + j) * width) + (x1 + i));
				if (a == 1.0f) {
					pixel[0] = col_conv[0];
					pixel[1] = col_conv[1];
					pixel[2] = col_conv[2];
					pixel[3] = 1.0f;
				}
				else {
					float alphatest;
					pixel[0] = (col_conv[0] * a) + (pixel[0] * ai);
					pixel[1] = (col_conv[1] * a) + (pixel[1] * ai);
					pixel[2] = (col_conv[2] * a) + (pixel[2] * ai);
					pixel[3] = (alphatest = (pixel[3] + a)) < 1.0f ? alphatest : 1.0f;
				}
			}
		}
	}
}
Example #6
0
/* update rectangular section of the brush image */
static void brush_painter_imbuf_update(BrushPainter *painter, ImBuf *oldtexibuf,
                                       int origx, int origy, int w, int h, int xt, int yt)
{
	Scene *scene = painter->scene;
	Brush *brush = painter->brush;

	const char *display_device = scene->display_settings.display_device;
	struct ColorManagedDisplay *display = IMB_colormanagement_display_get_named(display_device);

	rctf tex_mapping = painter->tex_mapping;
	rctf mask_mapping = painter->mask_mapping;
	struct ImagePool *pool = painter->pool;

	bool use_masking = painter->cache.use_masking;
	bool use_color_correction = painter->cache.use_color_correction;
	bool use_float = painter->cache.use_float;
	bool is_texbrush = painter->cache.is_texbrush;
	bool is_maskbrush = painter->cache.is_maskbrush;
	bool use_texture_old = (oldtexibuf != NULL);

	int x, y, thread = 0;
	float brush_rgb[3];

	ImBuf *ibuf = painter->cache.ibuf;
	ImBuf *texibuf = painter->cache.texibuf;
	unsigned short *mask = painter->cache.mask;

	/* get brush color */
	if (brush->imagepaint_tool == PAINT_TOOL_DRAW) {
		copy_v3_v3(brush_rgb, brush->rgb);

		if (use_color_correction) {
			IMB_colormanagement_display_to_scene_linear_v3(brush_rgb, display);
		}
	}
	else {
		brush_rgb[0] = 1.0f;
		brush_rgb[1] = 1.0f;
		brush_rgb[2] = 1.0f;
	}

	/* fill pixes */
	for (y = origy; y < h; y++) {
		for (x = origx; x < w; x++) {
			/* sample texture and multiply with brush color */
			float texco[3], rgba[4];

			if (!use_texture_old) {
				if (is_texbrush) {
					brush_imbuf_tex_co(&tex_mapping, x, y, texco);
					BKE_brush_sample_tex_3D(scene, brush, texco, rgba, thread, pool);
					/* TODO(sergey): Support texture paint color space. */
					if (!use_float) {
						IMB_colormanagement_display_to_scene_linear_v3(rgba, display);
					}
					mul_v3_v3(rgba, brush_rgb);
				}
				else {
					copy_v3_v3(rgba, brush_rgb);
					rgba[3] = 1.0f;
				}

				if (is_maskbrush) {
					brush_imbuf_tex_co(&mask_mapping, x, y, texco);
					rgba[3] *= BKE_brush_sample_masktex(scene, brush, texco, thread, pool);
				}
			}

			if (use_float) {
				/* handle float pixel */
				float *bf = ibuf->rect_float + (y * ibuf->x + x) * 4;
				float *tf = texibuf->rect_float + (y * texibuf->x + x) * 4;

				/* read from old texture buffer */
				if (use_texture_old) {
					float *otf = oldtexibuf->rect_float + ((y - origy + yt) * oldtexibuf->x + (x - origx + xt)) * 4;
					copy_v4_v4(rgba, otf);
				}

				/* write to new texture buffer */
				copy_v4_v4(tf, rgba);

				/* if not using masking, multiply in the mask now */
				if (!use_masking) {
					unsigned short *m = mask + (y * ibuf->x + x);
					rgba[3] *= *m * (1.0f / 65535.0f);
				}

				/* output premultiplied float image, mf was already premultiplied */
				mul_v3_v3fl(bf, rgba, rgba[3]);
				bf[3] = rgba[3];
			}
			else {
				unsigned char crgba[4];

				/* handle byte pixel */
				unsigned char *b = (unsigned char *)ibuf->rect + (y * ibuf->x + x) * 4;
				unsigned char *t = (unsigned char *)texibuf->rect + (y * texibuf->x + x) * 4;

				/* read from old texture buffer */
				if (use_texture_old) {
					unsigned char *ot = (unsigned char *)oldtexibuf->rect + ((y - origy + yt) * oldtexibuf->x + (x - origx + xt)) * 4;
					crgba[0] = ot[0];
					crgba[1] = ot[1];
					crgba[2] = ot[2];
					crgba[3] = ot[3];
				}
				else
					rgba_float_to_uchar(crgba, rgba);

				/* write to new texture buffer */
				t[0] = crgba[0];
				t[1] = crgba[1];
				t[2] = crgba[2];
				t[3] = crgba[3];

				/* if not using masking, multiply in the mask now */
				if (!use_masking) {
					unsigned short *m = mask + (y * ibuf->x + x);
					crgba[3] = (crgba[3] * (*m)) / 65535;
				}

				/* write to brush image buffer */
				b[0] = crgba[0];
				b[1] = crgba[1];
				b[2] = crgba[2];
				b[3] = crgba[3];
			}
		}
	}
}
Example #7
0
/* create imbuf with brush color */
static ImBuf *brush_painter_imbuf_new(BrushPainter *painter, int size)
{
	Scene *scene = painter->scene;
	Brush *brush = painter->brush;

	const char *display_device = scene->display_settings.display_device;
	struct ColorManagedDisplay *display = IMB_colormanagement_display_get_named(display_device);

	rctf tex_mapping = painter->tex_mapping;
	rctf mask_mapping = painter->mask_mapping;
	struct ImagePool *pool = painter->pool;

	bool use_masking = painter->cache.use_masking;
	bool use_color_correction = painter->cache.use_color_correction;
	bool use_float = painter->cache.use_float;
	bool is_texbrush = painter->cache.is_texbrush;
	bool is_maskbrush = painter->cache.is_maskbrush;

	float alpha = (use_masking) ? 1.0f : BKE_brush_alpha_get(scene, brush);
	int radius = BKE_brush_size_get(scene, brush);
	int xoff = -size * 0.5f + 0.5f;
	int yoff = -size * 0.5f + 0.5f;

	int x, y, thread = 0;
	float brush_rgb[3];

	/* allocate image buffer */
	ImBuf *ibuf = IMB_allocImBuf(size, size, 32, (use_float) ? IB_rectfloat : IB_rect);

	/* get brush color */
	if (brush->imagepaint_tool == PAINT_TOOL_DRAW) {
		copy_v3_v3(brush_rgb, brush->rgb);

		if (use_color_correction) {
			IMB_colormanagement_display_to_scene_linear_v3(brush_rgb, display);
		}
	}
	else {
		brush_rgb[0] = 1.0f;
		brush_rgb[1] = 1.0f;
		brush_rgb[2] = 1.0f;
	}

	/* fill image buffer */
	for (y = 0; y < size; y++) {
		for (x = 0; x < size; x++) {
			/* sample texture and multiply with brush color */
			float texco[3], rgba[4];

			if (is_texbrush) {
				brush_imbuf_tex_co(&tex_mapping, x, y, texco);
				BKE_brush_sample_tex_3D(scene, brush, texco, rgba, thread, pool);
				/* TODO(sergey): Support texture paint color space. */
				if (!use_float) {
					IMB_colormanagement_display_to_scene_linear_v3(rgba, display);
				}
				mul_v3_v3(rgba, brush_rgb);
			}
			else {
				copy_v3_v3(rgba, brush_rgb);
				rgba[3] = 1.0f;
			}

			if (is_maskbrush) {
				brush_imbuf_tex_co(&mask_mapping, x, y, texco);
				rgba[3] *= BKE_brush_sample_masktex(scene, brush, texco, thread, pool);
			}

			/* when not using masking, multiply in falloff and strength */
			if (!use_masking) {
				float xy[2] = {x + xoff, y + yoff};
				float len = len_v2(xy);

				rgba[3] *= alpha * BKE_brush_curve_strength_clamp(brush, len, radius);
			}

			if (use_float) {
				/* write to float pixel */
				float *dstf = ibuf->rect_float + (y * size + x) * 4;
				mul_v3_v3fl(dstf, rgba, rgba[3]); /* premultiply */
				dstf[3] = rgba[3];
			}
			else {
				/* write to byte pixel */
				unsigned char *dst = (unsigned char *)ibuf->rect + (y * size + x) * 4;

				rgb_float_to_uchar(dst, rgba);
				dst[3] = FTOCHAR(rgba[3]);
			}
		}
	}

	return ibuf;
}