diff options
author | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2010-04-18 06:03:19 +0400 |
---|---|---|
committer | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2010-04-18 06:03:19 +0400 |
commit | dfe2f8dc03267e041102837e92f547fb04881510 (patch) | |
tree | d9582c4667ce5b9e39e2adce40832aa4f44b4fe7 /source/blender/blenkernel/intern/colortools.c | |
parent | d7e08f2d33207fdf76b1b597ef0de9dec26e3987 (diff) | |
parent | 00e46ef739cf2bfddb8805af056aa59fd3b3c71c (diff) |
Merged changes in the trunk up to revision 28247.
Diffstat (limited to 'source/blender/blenkernel/intern/colortools.c')
-rw-r--r-- | source/blender/blenkernel/intern/colortools.c | 225 |
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; + } } |