Ejemplo n.º 1
0
static void imb_float_from_rect_linear(struct ImBuf *ibuf, float *fbuf)
{
	float *tof = fbuf;
	int i;
	unsigned char *to = (unsigned char *) ibuf->rect;

	for (i = ibuf->x * ibuf->y; i > 0; i--) 
	{
		tof[0] = srgb_to_linearrgb(((float)to[0])*(1.0f/255.0f));
		tof[1] = srgb_to_linearrgb(((float)to[1])*(1.0f/255.0f));
		tof[2] = srgb_to_linearrgb(((float)to[2])*(1.0f/255.0f));
		tof[3] = ((float)to[3])*(1.0f/255.0f);
		to += 4; 
		tof += 4;
	}
}
Ejemplo n.º 2
0
MINLINE void srgb_to_linearrgb_predivide_v4(float linear[4], const float srgb[4])
{
	float alpha, inv_alpha;

	if (srgb[3] == 1.0f || srgb[3] == 0.0f) {
		alpha = 1.0f;
		inv_alpha = 1.0f;
	}
	else {
		alpha = srgb[3];
		inv_alpha = 1.0f / alpha;
	}

	linear[0] = srgb_to_linearrgb(srgb[0] * inv_alpha) * alpha;
	linear[1] = srgb_to_linearrgb(srgb[1] * inv_alpha) * alpha;
	linear[2] = srgb_to_linearrgb(srgb[2] * inv_alpha) * alpha;
	linear[3] = srgb[3];
}
Ejemplo n.º 3
0
/* note: lift_lgg is just 2-lift, gamma_inv is 1.0/gamma */
DO_INLINE float colorbalance_lgg(float in, float lift_lgg, float gamma_inv, float gain)
{
	/* 1:1 match with the sequencer with linear/srgb conversions, the conversion isnt pretty
	 * but best keep it this way, sice testing for durian shows a similar calculation
	 * without lin/srgb conversions gives bad results (over-saturated shadows) with colors
	 * slightly below 1.0. some correction can be done but it ends up looking bad for shadows or lighter tones - campbell */
	float x= (((linearrgb_to_srgb(in) - 1.0f) * lift_lgg) + 1.0f) * gain;

	/* prevent NaN */
	if (x < 0.f) x = 0.f;

	return powf(srgb_to_linearrgb(x), gamma_inv);
}
Ejemplo n.º 4
0
void IMB_convert_profile(struct ImBuf *ibuf, int profile)
{
	int ok= FALSE;
	int i;

	unsigned char *rct= (unsigned char *)ibuf->rect;
	float *rctf= ibuf->rect_float;

	if(ibuf->profile == profile)
		return;

	if(ELEM(ibuf->profile, IB_PROFILE_NONE, IB_PROFILE_SRGB)) { /* from */
		if(profile == IB_PROFILE_LINEAR_RGB) { /* to */
			if(ibuf->rect_float) {
				for (i = ibuf->x * ibuf->y; i > 0; i--, rctf+=4) {
					rctf[0]= srgb_to_linearrgb(rctf[0]);
					rctf[1]= srgb_to_linearrgb(rctf[1]);
					rctf[2]= srgb_to_linearrgb(rctf[2]);
				}
			}
			if(ibuf->rect) {
				for (i = ibuf->x * ibuf->y; i > 0; i--, rct+=4) {
					rct[0]= (unsigned char)((srgb_to_linearrgb((float)rct[0]/255.0f) * 255.0f) + 0.5f);
					rct[1]= (unsigned char)((srgb_to_linearrgb((float)rct[1]/255.0f) * 255.0f) + 0.5f);
					rct[2]= (unsigned char)((srgb_to_linearrgb((float)rct[2]/255.0f) * 255.0f) + 0.5f);
				}
			}
			ok= TRUE;
		}
	}
	else if (ibuf->profile == IB_PROFILE_LINEAR_RGB) { /* from */
		if(ELEM(profile, IB_PROFILE_NONE, IB_PROFILE_SRGB)) { /* to */
			if(ibuf->rect_float) {
				for (i = ibuf->x * ibuf->y; i > 0; i--, rctf+=4) {
					rctf[0]= linearrgb_to_srgb(rctf[0]);
					rctf[1]= linearrgb_to_srgb(rctf[1]);
					rctf[2]= linearrgb_to_srgb(rctf[2]);
				}
			}
			if(ibuf->rect) {
				for (i = ibuf->x * ibuf->y; i > 0; i--, rct+=4) {
					rct[0]= (unsigned char)((linearrgb_to_srgb((float)rct[0]/255.0f) * 255.0f) + 0.5f);
					rct[1]= (unsigned char)((linearrgb_to_srgb((float)rct[1]/255.0f) * 255.0f) + 0.5f);
					rct[2]= (unsigned char)((linearrgb_to_srgb((float)rct[2]/255.0f) * 255.0f) + 0.5f);
				}
			}
			ok= TRUE;
		}
	}

	if(ok==FALSE){
		printf("IMB_convert_profile: failed profile conversion %d -> %d\n", ibuf->profile, profile);
		return;
	}

	ibuf->profile= profile;
}
Ejemplo n.º 5
0
MINLINE void srgb_to_linearrgb_v3_v3(float linear[3], const float srgb[3])
{
	linear[0] = srgb_to_linearrgb(srgb[0]);
	linear[1] = srgb_to_linearrgb(srgb[1]);
	linear[2] = srgb_to_linearrgb(srgb[2]);
}
static void compute_gradient_screen(RenderData *rd, NodeKeyingScreenData *keyingscreen_data, MovieClip *clip, CompBuf *screenbuf)
{
	MovieClipUser user = {0};
	MovieTracking *tracking = &clip->tracking;
	MovieTrackingTrack *track;
	VoronoiTriangulationPoint *triangulated_points;
	VoronoiSite *sites;
	ImBuf *ibuf;
	ListBase *tracksbase;
	ListBase edges = {NULL, NULL};
	int sites_total, triangulated_points_total, triangles_total;
	int (*triangles)[3];
	int i, x, y;
	float *rect = screenbuf->rect;

	if (keyingscreen_data->tracking_object[0]) {
		MovieTrackingObject *object = BKE_tracking_object_get_named(tracking, keyingscreen_data->tracking_object);

		if (!object)
			return;

		tracksbase = BKE_tracking_object_get_tracks(tracking, object);
	}
	else
		tracksbase = BKE_tracking_get_active_tracks(tracking);

	sites_total = BLI_countlist(tracksbase);

	if (!sites_total)
		return;

	BKE_movieclip_user_set_frame(&user, rd->cfra);
	ibuf = BKE_movieclip_get_ibuf(clip, &user);

	sites = MEM_callocN(sizeof(VoronoiSite) * sites_total, "keyingscreen voronoi sites");
	track = tracksbase->first;
	i = 0;
	while (track) {
		VoronoiSite *site = &sites[i];
		MovieTrackingMarker *marker = BKE_tracking_marker_get(track, rd->cfra);
		ImBuf *pattern_ibuf = BKE_tracking_get_pattern_imbuf(ibuf, track, marker, TRUE, FALSE);
		int j;

		zero_v3(site->color);

		if (pattern_ibuf) {
			for (j = 0; j < pattern_ibuf->x * pattern_ibuf->y; j++) {
				if (pattern_ibuf->rect_float) {
					add_v3_v3(site->color, &pattern_ibuf->rect_float[4 * j]);
				}
				else {
					unsigned char *rrgb = (unsigned char *)pattern_ibuf->rect;

					site->color[0] += srgb_to_linearrgb((float)rrgb[4 * j + 0] / 255.0f);
					site->color[1] += srgb_to_linearrgb((float)rrgb[4 * j + 1] / 255.0f);
					site->color[2] += srgb_to_linearrgb((float)rrgb[4 * j + 2] / 255.0f);
				}
			}

			mul_v3_fl(site->color, 1.0f / (pattern_ibuf->x * pattern_ibuf->y));
			IMB_freeImBuf(pattern_ibuf);
		}

		site->co[0] = marker->pos[0] * screenbuf->x;
		site->co[1] = marker->pos[1] * screenbuf->y;

		track = track->next;
		i++;
	}

	IMB_freeImBuf(ibuf);

	BLI_voronoi_compute(sites, sites_total, screenbuf->x, screenbuf->y, &edges);

	BLI_voronoi_triangulate(sites, sites_total, &edges, screenbuf->x, screenbuf->y,
	                        &triangulated_points, &triangulated_points_total,
                            &triangles, &triangles_total);

	for (y = 0; y < screenbuf->y; y++) {
		for (x = 0; x < screenbuf->x; x++) {
			int index = 4 * (y * screenbuf->x + x);

			rect[index + 0] = rect[index + 1] = rect[index + 2] = 0.0f;
			rect[index + 3] = 1.0f;

			for (i = 0; i < triangles_total; i++) {
				int *triangle = triangles[i];
				VoronoiTriangulationPoint *a = &triangulated_points[triangle[0]],
				                          *b = &triangulated_points[triangle[1]],
				                          *c = &triangulated_points[triangle[2]];
				float co[2] = {x, y}, w[3];

				if (barycentric_coords_v2(a->co, b->co, c->co, co, w)) {
					if (barycentric_inside_triangle_v2(w)) {
						rect[index + 0] += a->color[0] * w[0] + b->color[0] * w[1] + c->color[0] * w[2];
						rect[index + 1] += a->color[1] * w[0] + b->color[1] * w[1] + c->color[1] * w[2];
						rect[index + 2] += a->color[2] * w[0] + b->color[2] * w[1] + c->color[2] * w[2];
					}
				}
			}
		}
	}

	MEM_freeN(triangulated_points);
	MEM_freeN(triangles);
	MEM_freeN(sites);
	BLI_freelistN(&edges);
}
KeyingScreenOperation::TriangulationData *KeyingScreenOperation::buildVoronoiTriangulation()
{
	MovieClipUser user = {0};
	TriangulationData *triangulation;
	MovieTracking *tracking = &this->m_movieClip->tracking;
	MovieTrackingTrack *track;
	VoronoiSite *sites, *site;
	ImBuf *ibuf;
	ListBase *tracksbase;
	ListBase edges = {NULL, NULL};
	int sites_total;
	int i;
	int width = this->getWidth();
	int height = this->getHeight();
	int clip_frame = BKE_movieclip_remap_scene_to_clip_frame(this->m_movieClip, this->m_framenumber);

	if (this->m_trackingObject[0]) {
		MovieTrackingObject *object = BKE_tracking_object_get_named(tracking, this->m_trackingObject);

		if (!object)
			return NULL;

		tracksbase = BKE_tracking_object_get_tracks(tracking, object);
	}
	else
		tracksbase = BKE_tracking_get_active_tracks(tracking);

	/* count sites */
	for (track = (MovieTrackingTrack *) tracksbase->first, sites_total = 0; track; track = track->next) {
		MovieTrackingMarker *marker = BKE_tracking_marker_get(track, clip_frame);
		float pos[2];

		if (marker->flag & MARKER_DISABLED)
			continue;

		add_v2_v2v2(pos, marker->pos, track->offset);

		if (!IN_RANGE_INCL(pos[0], 0.0f, 1.0f) ||
		    !IN_RANGE_INCL(pos[1], 0.0f, 1.0f))
		{
			continue;
		}

		sites_total++;
	}

	if (!sites_total)
		return NULL;

	BKE_movieclip_user_set_frame(&user, clip_frame);
	ibuf = BKE_movieclip_get_ibuf(this->m_movieClip, &user);

	if (!ibuf)
		return NULL;

	triangulation = (TriangulationData *) MEM_callocN(sizeof(TriangulationData), "keying screen triangulation data");

	sites = (VoronoiSite *) MEM_callocN(sizeof(VoronoiSite) * sites_total, "keyingscreen voronoi sites");
	track = (MovieTrackingTrack *) tracksbase->first;
	for (track = (MovieTrackingTrack *) tracksbase->first, site = sites; track; track = track->next) {
		MovieTrackingMarker *marker = BKE_tracking_marker_get(track, clip_frame);
		ImBuf *pattern_ibuf;
		int j;
		float pos[2];

		if (marker->flag & MARKER_DISABLED)
			continue;

		add_v2_v2v2(pos, marker->pos, track->offset);

		if (!IN_RANGE_INCL(pos[0], 0.0f, 1.0f) ||
		    !IN_RANGE_INCL(pos[1], 0.0f, 1.0f))
		{
			continue;
		}

		pattern_ibuf = BKE_tracking_get_pattern_imbuf(ibuf, track, marker, TRUE, FALSE);

		zero_v3(site->color);

		if (pattern_ibuf) {
			for (j = 0; j < pattern_ibuf->x * pattern_ibuf->y; j++) {
				if (pattern_ibuf->rect_float) {
					add_v3_v3(site->color, &pattern_ibuf->rect_float[4 * j]);
				}
				else {
					unsigned char *rrgb = (unsigned char *)pattern_ibuf->rect;

					site->color[0] += srgb_to_linearrgb((float)rrgb[4 * j + 0] / 255.0f);
					site->color[1] += srgb_to_linearrgb((float)rrgb[4 * j + 1] / 255.0f);
					site->color[2] += srgb_to_linearrgb((float)rrgb[4 * j + 2] / 255.0f);
				}
			}

			mul_v3_fl(site->color, 1.0f / (pattern_ibuf->x * pattern_ibuf->y));
			IMB_freeImBuf(pattern_ibuf);
		}

		site->co[0] = pos[0] * width;
		site->co[1] = pos[1] * height;

		site++;
	}

	IMB_freeImBuf(ibuf);

	BLI_voronoi_compute(sites, sites_total, width, height, &edges);

	BLI_voronoi_triangulate(sites, sites_total, &edges, width, height,
	                        &triangulation->triangulated_points, &triangulation->triangulated_points_total,
	                        &triangulation->triangles, &triangulation->triangles_total);

	MEM_freeN(sites);
	BLI_freelistN(&edges);

	if (triangulation->triangles_total) {
		rctf *rect;
		rect = triangulation->triangles_AABB =
			(rctf *) MEM_callocN(sizeof(rctf) * triangulation->triangles_total, "voronoi triangulation AABB");

		for (i = 0; i < triangulation->triangles_total; i++, rect++) {
			int *triangle = triangulation->triangles[i];
			VoronoiTriangulationPoint *a = &triangulation->triangulated_points[triangle[0]],
			                          *b = &triangulation->triangulated_points[triangle[1]],
			                          *c = &triangulation->triangulated_points[triangle[2]];

			float min[2], max[2];

			INIT_MINMAX2(min, max);

			minmax_v2v2_v2(min, max, a->co);
			minmax_v2v2_v2(min, max, b->co);
			minmax_v2v2_v2(min, max, c->co);

			rect->xmin = min[0];
			rect->ymin = min[1];

			rect->xmax = max[0];
			rect->ymax = max[1];
		}
	}

	return triangulation;
}