Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/colortools.c
| Show First 20 Lines • Show All 1,377 Lines • ▼ Show 20 Lines | |||||
| /* if view_settings, it also applies this to byte buffers */ | /* if view_settings, it also applies this to byte buffers */ | ||||
| typedef struct ScopesUpdateData { | typedef struct ScopesUpdateData { | ||||
| Scopes *scopes; | Scopes *scopes; | ||||
| const ImBuf *ibuf; | const ImBuf *ibuf; | ||||
| struct ColormanageProcessor *cm_processor; | struct ColormanageProcessor *cm_processor; | ||||
| const unsigned char *display_buffer; | const unsigned char *display_buffer; | ||||
| const int ycc_mode; | const int ycc_mode; | ||||
| unsigned int *bin_lum, *bin_r, *bin_g, *bin_b, *bin_a; | |||||
| } ScopesUpdateData; | } ScopesUpdateData; | ||||
| typedef struct ScopesUpdateDataChunk { | typedef struct ScopesUpdateDataChunk { | ||||
| unsigned int bin_lum[256]; | unsigned int bin_lum[256]; | ||||
| unsigned int bin_r[256]; | unsigned int bin_r[256]; | ||||
| unsigned int bin_g[256]; | unsigned int bin_g[256]; | ||||
| unsigned int bin_b[256]; | unsigned int bin_b[256]; | ||||
| unsigned int bin_a[256]; | unsigned int bin_a[256]; | ||||
| ▲ Show 20 Lines • Show All 94 Lines • ▼ Show 20 Lines | if (do_sample_line) { | ||||
| save_sample_line(scopes, idx, fx, rgba, ycc); | save_sample_line(scopes, idx, fx, rgba, ycc); | ||||
| } | } | ||||
| rf += ibuf->channels; | rf += ibuf->channels; | ||||
| rc += ibuf->channels; | rc += ibuf->channels; | ||||
| } | } | ||||
| } | } | ||||
| static void scopes_update_finalize(void *__restrict userdata, void *__restrict userdata_chunk) | static void scopes_update_reduce(const void *__restrict UNUSED(userdata), | ||||
| { | void *__restrict chunk_join, | ||||
| const ScopesUpdateData *data = userdata; | void *__restrict chunk) | ||||
| const ScopesUpdateDataChunk *data_chunk = userdata_chunk; | { | ||||
| ScopesUpdateDataChunk *join_chunk = chunk_join; | |||||
| unsigned int *bin_lum = data->bin_lum; | const ScopesUpdateDataChunk *data_chunk = chunk; | ||||
| unsigned int *bin_r = data->bin_r; | |||||
| unsigned int *bin_g = data->bin_g; | unsigned int *bin_lum = join_chunk->bin_lum; | ||||
| unsigned int *bin_b = data->bin_b; | unsigned int *bin_r = join_chunk->bin_r; | ||||
| unsigned int *bin_a = data->bin_a; | unsigned int *bin_g = join_chunk->bin_g; | ||||
| unsigned int *bin_b = join_chunk->bin_b; | |||||
| unsigned int *bin_a = join_chunk->bin_a; | |||||
| const unsigned int *bin_lum_c = data_chunk->bin_lum; | const unsigned int *bin_lum_c = data_chunk->bin_lum; | ||||
| const unsigned int *bin_r_c = data_chunk->bin_r; | const unsigned int *bin_r_c = data_chunk->bin_r; | ||||
| const unsigned int *bin_g_c = data_chunk->bin_g; | const unsigned int *bin_g_c = data_chunk->bin_g; | ||||
| const unsigned int *bin_b_c = data_chunk->bin_b; | const unsigned int *bin_b_c = data_chunk->bin_b; | ||||
| const unsigned int *bin_a_c = data_chunk->bin_a; | const unsigned int *bin_a_c = data_chunk->bin_a; | ||||
| float(*minmax)[2] = data->scopes->minmax; | |||||
| const float *min = data_chunk->min; | const float *min = data_chunk->min; | ||||
| const float *max = data_chunk->max; | const float *max = data_chunk->max; | ||||
| for (int b = 256; b--;) { | for (int b = 256; b--;) { | ||||
| bin_lum[b] += bin_lum_c[b]; | bin_lum[b] += bin_lum_c[b]; | ||||
| bin_r[b] += bin_r_c[b]; | bin_r[b] += bin_r_c[b]; | ||||
| bin_g[b] += bin_g_c[b]; | bin_g[b] += bin_g_c[b]; | ||||
| bin_b[b] += bin_b_c[b]; | bin_b[b] += bin_b_c[b]; | ||||
| bin_a[b] += bin_a_c[b]; | bin_a[b] += bin_a_c[b]; | ||||
| } | } | ||||
| for (int c = 3; c--;) { | for (int c = 3; c--;) { | ||||
| if (min[c] < minmax[c][0]) { | if (min[c] < join_chunk->min[c]) { | ||||
| minmax[c][0] = min[c]; | join_chunk->min[c] = min[c]; | ||||
| } | } | ||||
| if (max[c] > minmax[c][1]) { | if (max[c] > join_chunk->max[c]) { | ||||
| minmax[c][1] = max[c]; | join_chunk->max[c] = max[c]; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| void BKE_scopes_update(Scopes *scopes, | void BKE_scopes_update(Scopes *scopes, | ||||
| ImBuf *ibuf, | ImBuf *ibuf, | ||||
| const ColorManagedViewSettings *view_settings, | const ColorManagedViewSettings *view_settings, | ||||
| const ColorManagedDisplaySettings *display_settings) | const ColorManagedDisplaySettings *display_settings) | ||||
| { | { | ||||
| int a; | int a; | ||||
| unsigned int nl, na, nr, ng, nb; | unsigned int nl, na, nr, ng, nb; | ||||
| double divl, diva, divr, divg, divb; | double divl, diva, divr, divg, divb; | ||||
| const unsigned char *display_buffer = NULL; | const unsigned char *display_buffer = NULL; | ||||
| uint bin_lum[256] = {0}, bin_r[256] = {0}, bin_g[256] = {0}, bin_b[256] = {0}, bin_a[256] = {0}; | |||||
| int ycc_mode = -1; | int ycc_mode = -1; | ||||
| void *cache_handle = NULL; | void *cache_handle = NULL; | ||||
| struct ColormanageProcessor *cm_processor = NULL; | struct ColormanageProcessor *cm_processor = NULL; | ||||
| if (ibuf->rect == NULL && ibuf->rect_float == NULL) { | if (ibuf->rect == NULL && ibuf->rect_float == NULL) { | ||||
| return; | return; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 79 Lines • ▼ Show 20 Lines | void BKE_scopes_update(Scopes *scopes, | ||||
| /* Keep number of threads in sync with the merge parts below. */ | /* Keep number of threads in sync with the merge parts below. */ | ||||
| ScopesUpdateData data = { | ScopesUpdateData data = { | ||||
| .scopes = scopes, | .scopes = scopes, | ||||
| .ibuf = ibuf, | .ibuf = ibuf, | ||||
| .cm_processor = cm_processor, | .cm_processor = cm_processor, | ||||
| .display_buffer = display_buffer, | .display_buffer = display_buffer, | ||||
| .ycc_mode = ycc_mode, | .ycc_mode = ycc_mode, | ||||
| .bin_lum = bin_lum, | |||||
| .bin_r = bin_r, | |||||
| .bin_g = bin_g, | |||||
| .bin_b = bin_b, | |||||
| .bin_a = bin_a, | |||||
| }; | }; | ||||
| ScopesUpdateDataChunk data_chunk = {{0}}; | ScopesUpdateDataChunk data_chunk = {{0}}; | ||||
| INIT_MINMAX(data_chunk.min, data_chunk.max); | INIT_MINMAX(data_chunk.min, data_chunk.max); | ||||
| TaskParallelSettings settings; | TaskParallelSettings settings; | ||||
| BLI_parallel_range_settings_defaults(&settings); | BLI_parallel_range_settings_defaults(&settings); | ||||
| settings.use_threading = (ibuf->y > 256); | settings.use_threading = (ibuf->y > 256); | ||||
| settings.userdata_chunk = &data_chunk; | settings.userdata_chunk = &data_chunk; | ||||
| settings.userdata_chunk_size = sizeof(data_chunk); | settings.userdata_chunk_size = sizeof(data_chunk); | ||||
| settings.func_finalize = scopes_update_finalize; | settings.func_reduce = scopes_update_reduce; | ||||
| BLI_task_parallel_range(0, ibuf->y, &data, scopes_update_cb, &settings); | BLI_task_parallel_range(0, ibuf->y, &data, scopes_update_cb, &settings); | ||||
| /* convert hist data to float (proportional to max count) */ | /* convert hist data to float (proportional to max count) */ | ||||
| nl = na = nr = nb = ng = 0; | nl = na = nr = nb = ng = 0; | ||||
| for (a = 0; a < 256; a++) { | for (a = 0; a < 256; a++) { | ||||
| if (bin_lum[a] > nl) { | if (data_chunk.bin_lum[a] > nl) { | ||||
| nl = bin_lum[a]; | nl = data_chunk.bin_lum[a]; | ||||
| } | } | ||||
| if (bin_r[a] > nr) { | if (data_chunk.bin_r[a] > nr) { | ||||
| nr = bin_r[a]; | nr = data_chunk.bin_r[a]; | ||||
| } | } | ||||
| if (bin_g[a] > ng) { | if (data_chunk.bin_g[a] > ng) { | ||||
| ng = bin_g[a]; | ng = data_chunk.bin_g[a]; | ||||
| } | } | ||||
| if (bin_b[a] > nb) { | if (data_chunk.bin_b[a] > nb) { | ||||
| nb = bin_b[a]; | nb = data_chunk.bin_b[a]; | ||||
| } | } | ||||
| if (bin_a[a] > na) { | if (data_chunk.bin_a[a] > na) { | ||||
| na = bin_a[a]; | na = data_chunk.bin_a[a]; | ||||
| } | } | ||||
| } | } | ||||
| divl = nl ? 1.0 / (double)nl : 1.0; | divl = nl ? 1.0 / (double)nl : 1.0; | ||||
| diva = na ? 1.0 / (double)na : 1.0; | diva = na ? 1.0 / (double)na : 1.0; | ||||
| divr = nr ? 1.0 / (double)nr : 1.0; | divr = nr ? 1.0 / (double)nr : 1.0; | ||||
| divg = ng ? 1.0 / (double)ng : 1.0; | divg = ng ? 1.0 / (double)ng : 1.0; | ||||
| divb = nb ? 1.0 / (double)nb : 1.0; | divb = nb ? 1.0 / (double)nb : 1.0; | ||||
| for (a = 0; a < 256; a++) { | for (a = 0; a < 256; a++) { | ||||
| scopes->hist.data_luma[a] = bin_lum[a] * divl; | scopes->hist.data_luma[a] = data_chunk.bin_lum[a] * divl; | ||||
| scopes->hist.data_r[a] = bin_r[a] * divr; | scopes->hist.data_r[a] = data_chunk.bin_r[a] * divr; | ||||
| scopes->hist.data_g[a] = bin_g[a] * divg; | scopes->hist.data_g[a] = data_chunk.bin_g[a] * divg; | ||||
| scopes->hist.data_b[a] = bin_b[a] * divb; | scopes->hist.data_b[a] = data_chunk.bin_b[a] * divb; | ||||
| scopes->hist.data_a[a] = bin_a[a] * diva; | scopes->hist.data_a[a] = data_chunk.bin_a[a] * diva; | ||||
| } | } | ||||
| if (cm_processor) { | if (cm_processor) { | ||||
| IMB_colormanagement_processor_free(cm_processor); | IMB_colormanagement_processor_free(cm_processor); | ||||
| } | } | ||||
| if (cache_handle) { | if (cache_handle) { | ||||
| IMB_display_buffer_release(cache_handle); | IMB_display_buffer_release(cache_handle); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 132 Lines • Show Last 20 Lines | |||||