diff options
author | shumkovnd <shumkovnd@yandex-team.com> | 2023-11-10 14:39:34 +0300 |
---|---|---|
committer | shumkovnd <shumkovnd@yandex-team.com> | 2023-11-10 16:42:24 +0300 |
commit | 77eb2d3fdcec5c978c64e025ced2764c57c00285 (patch) | |
tree | c51edb0748ca8d4a08d7c7323312c27ba1a8b79a /contrib/python/matplotlib/py2/src/_image.h | |
parent | dd6d20cadb65582270ac23f4b3b14ae189704b9d (diff) | |
download | ydb-77eb2d3fdcec5c978c64e025ced2764c57c00285.tar.gz |
KIKIMR-19287: add task_stats_drawing script
Diffstat (limited to 'contrib/python/matplotlib/py2/src/_image.h')
-rw-r--r-- | contrib/python/matplotlib/py2/src/_image.h | 200 |
1 files changed, 200 insertions, 0 deletions
diff --git a/contrib/python/matplotlib/py2/src/_image.h b/contrib/python/matplotlib/py2/src/_image.h new file mode 100644 index 0000000000..629714d2ec --- /dev/null +++ b/contrib/python/matplotlib/py2/src/_image.h @@ -0,0 +1,200 @@ +/* -*- mode: c++; c-basic-offset: 4 -*- */ + +/* image.h + * + */ + +#ifndef _IMAGE_H +#define _IMAGE_H + +#include <vector> + + +// utilities for irregular grids +void _bin_indices_middle( + unsigned int *irows, int nrows, const float *ys1, unsigned long ny, float dy, float y_min); +void _bin_indices_middle_linear(float *arows, + unsigned int *irows, + int nrows, + const float *y, + unsigned long ny, + float dy, + float y_min); +void _bin_indices(int *irows, int nrows, const double *y, unsigned long ny, double sc, double offs); +void _bin_indices_linear( + float *arows, int *irows, int nrows, double *y, unsigned long ny, double sc, double offs); + +template <class CoordinateArray, class ColorArray, class OutputArray> +void pcolor(CoordinateArray &x, + CoordinateArray &y, + ColorArray &d, + unsigned int rows, + unsigned int cols, + float bounds[4], + int interpolation, + OutputArray &out) +{ + if (rows >= 32768 || cols >= 32768) { + throw std::runtime_error("rows and cols must both be less than 32768"); + } + + float x_min = bounds[0]; + float x_max = bounds[1]; + float y_min = bounds[2]; + float y_max = bounds[3]; + float width = x_max - x_min; + float height = y_max - y_min; + float dx = width / ((float)cols); + float dy = height / ((float)rows); + + // Check we have something to output to + if (rows == 0 || cols == 0) { + throw std::runtime_error("Cannot scale to zero size"); + } + + if (d.dim(2) != 4) { + throw std::runtime_error("data must be in RGBA format"); + } + + // Check dimensions match + unsigned long nx = x.dim(0); + unsigned long ny = y.dim(0); + if (nx != (unsigned long)d.dim(1) || ny != (unsigned long)d.dim(0)) { + throw std::runtime_error("data and axis dimensions do not match"); + } + + // Allocate memory for pointer arrays + std::vector<unsigned int> rowstarts(rows); + std::vector<unsigned int> colstarts(cols); + + // Calculate the pointer arrays to map input x to output x + unsigned int i, j; + unsigned int *colstart = &colstarts[0]; + unsigned int *rowstart = &rowstarts[0]; + const float *xs1 = x.data(); + const float *ys1 = y.data(); + + // Copy data to output buffer + const unsigned char *start; + const unsigned char *inposition; + size_t inrowsize = nx * 4; + size_t rowsize = cols * 4; + unsigned char *position = (unsigned char *)out.data(); + unsigned char *oldposition = NULL; + start = d.data(); + + if (interpolation == NEAREST) { + _bin_indices_middle(colstart, cols, xs1, nx, dx, x_min); + _bin_indices_middle(rowstart, rows, ys1, ny, dy, y_min); + for (i = 0; i < rows; i++, rowstart++) { + if (i > 0 && *rowstart == 0) { + memcpy(position, oldposition, rowsize * sizeof(unsigned char)); + oldposition = position; + position += rowsize; + } else { + oldposition = position; + start += *rowstart * inrowsize; + inposition = start; + for (j = 0, colstart = &colstarts[0]; j < cols; j++, position += 4, colstart++) { + inposition += *colstart * 4; + memcpy(position, inposition, 4 * sizeof(unsigned char)); + } + } + } + } else if (interpolation == BILINEAR) { + std::vector<float> acols(cols); + std::vector<float> arows(rows); + + _bin_indices_middle_linear(&acols[0], colstart, cols, xs1, nx, dx, x_min); + _bin_indices_middle_linear(&arows[0], rowstart, rows, ys1, ny, dy, y_min); + double a00, a01, a10, a11, alpha, beta; + + // Copy data to output buffer + for (i = 0; i < rows; i++) { + for (j = 0; j < cols; j++) { + alpha = arows[i]; + beta = acols[j]; + + a00 = alpha * beta; + a01 = alpha * (1.0 - beta); + a10 = (1.0 - alpha) * beta; + a11 = 1.0 - a00 - a01 - a10; + + for (size_t k = 0; k < 4; ++k) { + position[k] = + d(rowstart[i], colstart[j], k) * a00 + + d(rowstart[i], colstart[j] + 1, k) * a01 + + d(rowstart[i] + 1, colstart[j], k) * a10 + + d(rowstart[i] + 1, colstart[j] + 1, k) * a11; + } + position += 4; + } + } + } +} + +template <class CoordinateArray, class ColorArray, class Color, class OutputArray> +void pcolor2(CoordinateArray &x, + CoordinateArray &y, + ColorArray &d, + unsigned int rows, + unsigned int cols, + float bounds[4], + Color &bg, + OutputArray &out) +{ + double x_left = bounds[0]; + double x_right = bounds[1]; + double y_bot = bounds[2]; + double y_top = bounds[3]; + + // Check we have something to output to + if (rows == 0 || cols == 0) { + throw std::runtime_error("rows or cols is zero; there are no pixels"); + } + + if (d.dim(2) != 4) { + throw std::runtime_error("data must be in RGBA format"); + } + + // Check dimensions match + unsigned long nx = x.dim(0); + unsigned long ny = y.dim(0); + if (nx != (unsigned long)d.dim(1) + 1 || ny != (unsigned long)d.dim(0) + 1) { + throw std::runtime_error("data and axis bin boundary dimensions are incompatible"); + } + + if (bg.dim(0) != 4) { + throw std::runtime_error("bg must be in RGBA format"); + } + + std::vector<int> irows(rows); + std::vector<int> jcols(cols); + + // Calculate the pointer arrays to map input x to output x + size_t i, j; + const double *x0 = x.data(); + const double *y0 = y.data(); + double sx = cols / (x_right - x_left); + double sy = rows / (y_top - y_bot); + _bin_indices(&jcols[0], cols, x0, nx, sx, x_left); + _bin_indices(&irows[0], rows, y0, ny, sy, y_bot); + + // Copy data to output buffer + unsigned char *position = (unsigned char *)out.data(); + + for (i = 0; i < rows; i++) { + for (j = 0; j < cols; j++) { + if (irows[i] == -1 || jcols[j] == -1) { + memcpy(position, (const unsigned char *)bg.data(), 4 * sizeof(unsigned char)); + } else { + for (size_t k = 0; k < 4; ++k) { + position[k] = d(irows[i], jcols[j], k); + } + } + position += 4; + } + } +} + +#endif |