Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/intern/colortools.c')
-rw-r--r--source/blender/blenkernel/intern/colortools.c225
1 files changed, 182 insertions, 43 deletions
diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c
index 4c0c10c127a..353adf932a5 100644
--- a/source/blender/blenkernel/intern/colortools.c
+++ b/source/blender/blenkernel/intern/colortools.c
@@ -885,6 +885,8 @@ void curvemapping_table_RGBA(CurveMapping *cumap, float **array, int *size)
/* ***************** Histogram **************** */
+#define INV_255 (1.f/255.f)
+
DO_INLINE int get_bin_float(float f)
{
int bin= (int)(f*255);
@@ -897,59 +899,172 @@ DO_INLINE int get_bin_float(float f)
return bin;
}
+DO_INLINE void save_sample_line(Scopes *scopes, const int idx, const float fx, float *rgb, float *ycc)
+{
+ float yuv[3];
+
+ /* vectorscope*/
+ rgb_to_yuv(rgb[0], rgb[1], rgb[2], &yuv[0], &yuv[1], &yuv[2]);
+ scopes->vecscope[idx + 0] = yuv[1];
+ scopes->vecscope[idx + 1] = yuv[2];
-void histogram_update(Histogram *hist, ImBuf *ibuf)
+ /* waveform */
+ switch (scopes->wavefrm_mode) {
+ case SCOPES_WAVEFRM_RGB:
+ scopes->waveform_1[idx + 0] = fx;
+ scopes->waveform_1[idx + 1] = rgb[0];
+ scopes->waveform_2[idx + 0] = fx;
+ scopes->waveform_2[idx + 1] = rgb[1];
+ scopes->waveform_3[idx + 0] = fx;
+ scopes->waveform_3[idx + 1] = rgb[2];
+ break;
+ case SCOPES_WAVEFRM_LUM:
+ scopes->waveform_1[idx + 0] = fx;
+ scopes->waveform_1[idx + 1] = ycc[0];
+ break;
+ case SCOPES_WAVEFRM_YCC_JPEG:
+ case SCOPES_WAVEFRM_YCC_709:
+ case SCOPES_WAVEFRM_YCC_601:
+ scopes->waveform_1[idx + 0] = fx;
+ scopes->waveform_1[idx + 1] = ycc[0];
+ scopes->waveform_2[idx + 0] = fx;
+ scopes->waveform_2[idx + 1] = ycc[1];
+ scopes->waveform_3[idx + 0] = fx;
+ scopes->waveform_3[idx + 1] = ycc[2];
+ break;
+ }
+}
+
+void scopes_update(Scopes *scopes, ImBuf *ibuf, int use_color_management)
{
- int x, y, n;
- double div;
+ int x, y, c, n, nl;
+ double div, divl;
float *rf;
unsigned char *rc;
- unsigned int *bin_r, *bin_g, *bin_b;
-
- if (hist->ok == 1 ) return;
-
- if (hist->xmax == 0.f) hist->xmax = 1.f;
- if (hist->ymax == 0.f) hist->ymax = 1.f;
-
+ unsigned int *bin_r, *bin_g, *bin_b, *bin_lum;
+ int savedlines, saveline;
+ float rgb[3], ycc[3];
+ int ycc_mode;
+
+ if (scopes->ok == 1 ) return;
+
+ if (scopes->hist.ymax == 0.f) scopes->hist.ymax = 1.f;
+
/* hmmmm */
if (!(ELEM(ibuf->channels, 3, 4))) return;
-
- hist->channels = 3;
-
+ scopes->hist.channels = 3;
+ scopes->hist.x_resolution = 256;
+
+ switch (scopes->wavefrm_mode) {
+ case SCOPES_WAVEFRM_RGB:
+ ycc_mode = -1;
+ break;
+ case SCOPES_WAVEFRM_LUM:
+ case SCOPES_WAVEFRM_YCC_JPEG:
+ ycc_mode = BLI_YCC_JFIF_0_255;
+ break;
+ case SCOPES_WAVEFRM_YCC_601:
+ ycc_mode = BLI_YCC_ITU_BT601;
+ break;
+ case SCOPES_WAVEFRM_YCC_709:
+ ycc_mode = BLI_YCC_ITU_BT709;
+ break;
+ }
+
+ /* temp table to count pix value for histo */
bin_r = MEM_callocN(256 * sizeof(unsigned int), "temp historgram bins");
bin_g = MEM_callocN(256 * sizeof(unsigned int), "temp historgram bins");
bin_b = MEM_callocN(256 * sizeof(unsigned int), "temp historgram bins");
+ bin_lum = MEM_callocN(256 * sizeof(unsigned int), "temp historgram bins");
+
+ /* convert to number of lines with logarithmic scale */
+ scopes->sample_lines = (scopes->accuracy*0.01) * (scopes->accuracy*0.01) * ibuf->y;
- if (ibuf->rect_float) {
- hist->x_resolution = 256;
-
- /* divide into bins */
- rf = ibuf->rect_float;
- for (y = 0; y < ibuf->y; y++) {
- for (x = 0; x < ibuf->x; x++) {
- bin_r[ get_bin_float(rf[0]) ] += 1;
- bin_g[ get_bin_float(rf[1]) ] += 1;
- bin_b[ get_bin_float(rf[2]) ] += 1;
- rf+= ibuf->channels;
- }
- }
+ if (scopes->sample_full)
+ scopes->sample_lines = ibuf->y;
+
+ /* scan the image */
+ savedlines=0;
+ for (c=0; c<3; c++) {
+ scopes->minmax[c][0]=25500.0f;
+ scopes->minmax[c][1]=-25500.0f;
}
- else if (ibuf->rect) {
- hist->x_resolution = 256;
-
+
+ scopes->waveform_tot = ibuf->x*scopes->sample_lines;
+
+ if (scopes->waveform_1)
+ MEM_freeN(scopes->waveform_1);
+ if (scopes->waveform_2)
+ MEM_freeN(scopes->waveform_2);
+ if (scopes->waveform_3)
+ MEM_freeN(scopes->waveform_3);
+ if (scopes->vecscope)
+ MEM_freeN(scopes->vecscope);
+
+ scopes->waveform_1= MEM_callocN(scopes->waveform_tot * 2 * sizeof(float), "waveform point channel 1");
+ scopes->waveform_2= MEM_callocN(scopes->waveform_tot * 2 * sizeof(float), "waveform point channel 2");
+ scopes->waveform_3= MEM_callocN(scopes->waveform_tot * 2 * sizeof(float), "waveform point channel 3");
+ scopes->vecscope= MEM_callocN(scopes->waveform_tot * 2 * sizeof(float), "vectorscope point channel");
+
+ if (ibuf->rect_float)
+ rf = ibuf->rect_float;
+ else if (ibuf->rect)
rc = (unsigned char *)ibuf->rect;
- for (y = 0; y < ibuf->y; y++) {
- for (x = 0; x < ibuf->x; x++) {
- bin_r[ rc[0] ] += 1;
- bin_g[ rc[1] ] += 1;
- bin_b[ rc[2] ] += 1;
- rc += ibuf->channels;
+
+ for (y = 0; y < ibuf->y; y++) {
+ if (savedlines<scopes->sample_lines && y>=((savedlines)*ibuf->y)/(scopes->sample_lines+1)) {
+ saveline=1;
+ } else saveline=0;
+ for (x = 0; x < ibuf->x; x++) {
+
+ if (ibuf->rect_float) {
+ if (use_color_management)
+ linearrgb_to_srgb_v3_v3(rgb, rf);
+ else
+ copy_v3_v3(rgb, rf);
+ }
+ else if (ibuf->rect) {
+ for (c=0; c<3; c++)
+ rgb[c] = rc[c] * INV_255;
+ }
+ /* check for min max */
+ if(ycc_mode == -1 ) {
+ for (c=0; c<3; c++) {
+ if (rgb[c] < scopes->minmax[c][0]) scopes->minmax[c][0] = rgb[c];
+ if (rgb[c] > scopes->minmax[c][1]) scopes->minmax[c][1] = rgb[c];
+ }
}
+ else {
+ rgb_to_ycc(rgb[0],rgb[1],rgb[2],&ycc[0],&ycc[1],&ycc[2], ycc_mode);
+ for (c=0; c<3; c++) {
+ ycc[c] *=INV_255;
+ if (ycc[c] < scopes->minmax[c][0]) scopes->minmax[c][0] = ycc[c];
+ if (ycc[c] > scopes->minmax[c][1]) scopes->minmax[c][1] = ycc[c];
+ }
+ }
+ /* increment count for histo*/
+ bin_r[ get_bin_float(rgb[0]) ] += 1;
+ bin_g[ get_bin_float(rgb[1]) ] += 1;
+ bin_b[ get_bin_float(rgb[2]) ] += 1;
+ bin_lum[ get_bin_float(ycc[0]) ] += 1;
+
+ /* save sample if needed */
+ if(saveline) {
+ const float fx = (float)x / (float)ibuf->x;
+ const int idx = 2*(ibuf->x*savedlines+x);
+ save_sample_line(scopes, idx, fx, rgb, ycc);
+ }
+
+ rf+= ibuf->channels;
+ rc+= ibuf->channels;
}
+ if (saveline)
+ savedlines +=1;
}
-
- /* convert to float */
+
+ /* convert hist data to float (proportional to max count) */
n=0;
+ nl=0;
for (x=0; x<256; x++) {
if (bin_r[x] > n)
n = bin_r[x];
@@ -957,17 +1072,41 @@ void histogram_update(Histogram *hist, ImBuf *ibuf)
n = bin_g[x];
if (bin_b[x] > n)
n = bin_b[x];
+ if (bin_lum[x] > nl)
+ nl = bin_lum[x];
}
div = 1.f/(double)n;
+ divl = 1.f/(double)nl;
for (x=0; x<256; x++) {
- hist->data_r[x] = bin_r[x] * div;
- hist->data_g[x] = bin_g[x] * div;
- hist->data_b[x] = bin_b[x] * div;
+ scopes->hist.data_r[x] = bin_r[x] * div;
+ scopes->hist.data_g[x] = bin_g[x] * div;
+ scopes->hist.data_b[x] = bin_b[x] * div;
+ scopes->hist.data_luma[x] = bin_lum[x] * divl;
}
-
MEM_freeN(bin_r);
MEM_freeN(bin_g);
MEM_freeN(bin_b);
-
- hist->ok=1;
+ MEM_freeN(bin_lum);
+
+ scopes->ok = 1;
+}
+
+void scopes_free(Scopes *scopes)
+{
+ if (scopes->waveform_1) {
+ MEM_freeN(scopes->waveform_1);
+ scopes->waveform_1 = NULL;
+ }
+ if (scopes->waveform_2) {
+ MEM_freeN(scopes->waveform_2);
+ scopes->waveform_2 = NULL;
+ }
+ if (scopes->waveform_3) {
+ MEM_freeN(scopes->waveform_3);
+ scopes->waveform_3 = NULL;
+ }
+ if (scopes->vecscope) {
+ MEM_freeN(scopes->vecscope);
+ scopes->vecscope = NULL;
+ }
}