83 lines
3.1 KiB
C++
83 lines
3.1 KiB
C++
#pragma once
|
|
#include <algorithm>
|
|
#include <cmath>
|
|
#include <utility>
|
|
#include "../architecture/Render_Lease.h"
|
|
#include "../base/Color.h"
|
|
#include "../base/Geometry.h"
|
|
#include "../plottable/Interpolation_p.h"
|
|
#include "../render/Canvas.h"
|
|
#include "../render/Image.h"
|
|
#include "Color_Map.h"
|
|
#include "Raster_Image.h"
|
|
namespace renderive {
|
|
class Raster_Image_Buffer {
|
|
public:
|
|
[[nodiscard]] int width() const {
|
|
return image_data.width();
|
|
}
|
|
[[nodiscard]] int height() const {
|
|
return image_data.height();
|
|
}
|
|
[[nodiscard]] bool is_null() const {
|
|
return image_data.empty();
|
|
}
|
|
[[nodiscard]] const Image& image() const {
|
|
return image_data;
|
|
}
|
|
Image& image() {
|
|
return image_data;
|
|
}
|
|
void set_image(Image image) {
|
|
image_data = std::move(image);
|
|
}
|
|
void resize(int width, int height) {
|
|
image_data.resize(width, height);
|
|
}
|
|
void fill(Color color) {
|
|
image_data.fill(color);
|
|
}
|
|
Pixel* row(int row) {
|
|
return image_data.row(row);
|
|
}
|
|
void write_color_mapped_row(int row_index, const double* values, int first_col, int last_col, double value_start_coord, double rate, const Color_Map& color_map, Color background_color) {
|
|
Pixel* line = row(row_index);
|
|
Pixel bg = premultiply(background_color);
|
|
std::fill(line, line + image_data.width(), bg);
|
|
for (int col = first_col; col <= last_col; ++col) {
|
|
int color_offset = static_cast<int>((values[col] - value_start_coord) * rate);
|
|
line[col] = color_map.at_offset(color_offset);
|
|
}
|
|
}
|
|
void write_normalized_grid(const double* values, int width, int height, const Color_Map& color_map) {
|
|
for (int row_index = 0; row_index < height; ++row_index) {
|
|
Pixel* line = row(row_index);
|
|
const double* source = values + row_index * width;
|
|
for (int col = 0; col < width; ++col) {
|
|
line[col] = color_map.at_normalized(source[col]);
|
|
}
|
|
}
|
|
}
|
|
void draw(Canvas& canvas, const RectF& target_rect, Image_Interpolation_Mode mode = Image_Interpolation_Mode::Nearest) const {
|
|
draw(canvas, target_rect, RectF{0.0, 0.0, static_cast<double>(image_data.width()), static_cast<double>(image_data.height())}, mode);
|
|
}
|
|
void draw(Canvas& canvas, const RectF& target_rect, const RectF& source_rect, Image_Interpolation_Mode mode) const {
|
|
if (image_data.empty())
|
|
return;
|
|
canvas.save();
|
|
if (mode == Image_Interpolation_Mode::Bicubic) {
|
|
Size target_size{std::max(1, static_cast<int>(std::ceil(std::abs(target_rect.width)))), std::max(1, static_cast<int>(std::ceil(std::abs(target_rect.height))))};
|
|
Image scaled_image = bicubic_scale(image_data, source_rect, target_size);
|
|
canvas.draw_image(target_rect, scaled_image);
|
|
}
|
|
else {
|
|
canvas.set_image_interpolation(mode);
|
|
canvas.draw_image(target_rect, image_data, source_rect);
|
|
}
|
|
canvas.restore();
|
|
}
|
|
private:
|
|
Image image_data;
|
|
};
|
|
} // namespace renderive
|