Example #1
0
void BKE_histogram_update_sample_line(Histogram *hist, ImBuf *ibuf, const ColorManagedViewSettings *view_settings,
                                      const ColorManagedDisplaySettings *display_settings)
{
	int i, x, y;
	float *fp;
	float rgb[3];
	unsigned char *cp;

	int x1 = 0.5f + hist->co[0][0] * ibuf->x;
	int x2 = 0.5f + hist->co[1][0] * ibuf->x;
	int y1 = 0.5f + hist->co[0][1] * ibuf->y;
	int y2 = 0.5f + hist->co[1][1] * ibuf->y;

	struct ColormanageProcessor *cm_processor = NULL;

	hist->channels = 3;
	hist->x_resolution = 256;
	hist->xmax = 1.0f;
	/* hist->ymax = 1.0f; */ /* now do this on the operator _only_ */

	if (ibuf->rect == NULL && ibuf->rect_float == NULL) return;

	if (ibuf->rect_float)
		cm_processor = IMB_colormanagement_display_processor_new(view_settings, display_settings);

	for (i = 0; i < 256; i++) {
		x = (int)(0.5f + x1 + (float)i * (x2 - x1) / 255.0f);
		y = (int)(0.5f + y1 + (float)i * (y2 - y1) / 255.0f);

		if (x < 0 || y < 0 || x >= ibuf->x || y >= ibuf->y) {
			hist->data_luma[i] = hist->data_r[i] = hist->data_g[i] = hist->data_b[i] = hist->data_a[i] = 0.0f;
		}
		else {
			if (ibuf->rect_float) {
				fp = (ibuf->rect_float + (ibuf->channels) * (y * ibuf->x + x));

				copy_v3_v3(rgb, fp);
				IMB_colormanagement_processor_apply_v3(cm_processor, rgb);

				hist->data_luma[i]  = rgb_to_luma(rgb);
				hist->data_r[i]     = rgb[0];
				hist->data_g[i]     = rgb[1];
				hist->data_b[i]     = rgb[2];
				hist->data_a[i]     = fp[3];
			}
			else if (ibuf->rect) {
				cp = (unsigned char *)(ibuf->rect + y * ibuf->x + x);
				hist->data_luma[i]  = (float)rgb_to_luma_byte(cp) / 255.0f;
				hist->data_r[i]     = (float)cp[0] / 255.0f;
				hist->data_g[i]     = (float)cp[1] / 255.0f;
				hist->data_b[i]     = (float)cp[2] / 255.0f;
				hist->data_a[i]     = (float)cp[3] / 255.0f;
			}
		}
	}

	if (cm_processor)
		IMB_colormanagement_processor_free(cm_processor);
}
static void scopes_update_cb(void *userdata, void *userdata_chunk, const int y, const int UNUSED(threadid))
{
	const ScopesUpdateData *data = userdata;

	Scopes *scopes = data->scopes;
	const ImBuf *ibuf = data->ibuf;
	struct ColormanageProcessor *cm_processor = data->cm_processor;
	const unsigned char *display_buffer = data->display_buffer;
	const int ycc_mode = data->ycc_mode;

	ScopesUpdateDataChunk *data_chunk = userdata_chunk;
	unsigned int *bin_lum = data_chunk->bin_lum;
	unsigned int *bin_r = data_chunk->bin_r;
	unsigned int *bin_g = data_chunk->bin_g;
	unsigned int *bin_b = data_chunk->bin_b;
	unsigned int *bin_a = data_chunk->bin_a;
	float *min = data_chunk->min;
	float *max = data_chunk->max;

	const float *rf = NULL;
	const unsigned char *rc = NULL;
	const int rows_per_sample_line = ibuf->y / scopes->sample_lines;
	const int savedlines = y / rows_per_sample_line;
	const bool do_sample_line = (savedlines < scopes->sample_lines) && (y % rows_per_sample_line) == 0;
	const bool is_float = (ibuf->rect_float != NULL);

	if (is_float)
		rf = ibuf->rect_float + ((size_t)y) * ibuf->x * ibuf->channels;
	else {
		rc = display_buffer + ((size_t)y) * ibuf->x * ibuf->channels;
	}

	for (int x = 0; x < ibuf->x; x++) {
		float rgba[4], ycc[3], luma;

		if (is_float) {
			switch (ibuf->channels) {
				case 4:
					copy_v4_v4(rgba, rf);
					IMB_colormanagement_processor_apply_v4(cm_processor, rgba);
					break;
				case 3:
					copy_v3_v3(rgba, rf);
					IMB_colormanagement_processor_apply_v3(cm_processor, rgba);
					rgba[3] = 1.0f;
					break;
				case 2:
					copy_v3_fl(rgba, rf[0]);
					rgba[3] = rf[1];
					break;
				case 1:
					copy_v3_fl(rgba, rf[0]);
					rgba[3] = 1.0f;
					break;
				default:
					BLI_assert(0);
			}
		}
		else {
			for (int c = 4; c--;)
				rgba[c] = rc[c] * INV_255;
		}

		/* we still need luma for histogram */
		luma = IMB_colormanagement_get_luminance(rgba);

		/* check for min max */
		if (ycc_mode == -1) {
			minmax_v3v3_v3(min, max, rgba);
		}
		else {
			rgb_to_ycc(rgba[0], rgba[1], rgba[2], &ycc[0], &ycc[1], &ycc[2], ycc_mode);
			mul_v3_fl(ycc, INV_255);
			minmax_v3v3_v3(min, max, ycc);
		}
		/* increment count for histo*/
		bin_lum[get_bin_float(luma)]++;
		bin_r[get_bin_float(rgba[0])]++;
		bin_g[get_bin_float(rgba[1])]++;
		bin_b[get_bin_float(rgba[2])]++;
		bin_a[get_bin_float(rgba[3])]++;

		/* save sample if needed */
		if (do_sample_line) {
			const float fx = (float)x / (float)ibuf->x;
			const int idx = 2 * (ibuf->x * savedlines + x);
			save_sample_line(scopes, idx, fx, rgba, ycc);
		}

		rf += ibuf->channels;
		rc += ibuf->channels;
	}
}