改进
This commit is contained in:
@@ -1,8 +1,6 @@
|
||||
#include "Pixel_Frame.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
#if defined(_M_X64) || defined(__x86_64__)
|
||||
#include <tmmintrin.h>
|
||||
#endif
|
||||
@@ -10,13 +8,6 @@
|
||||
namespace renderive::web {
|
||||
namespace {
|
||||
|
||||
void write_u32_le(char* target, std::uint32_t value) {
|
||||
target[0] = static_cast<char>(value & 0xffU);
|
||||
target[1] = static_cast<char>((value >> 8U) & 0xffU);
|
||||
target[2] = static_cast<char>((value >> 16U) & 0xffU);
|
||||
target[3] = static_cast<char>((value >> 24U) & 0xffU);
|
||||
}
|
||||
|
||||
std::uint8_t flatten(std::uint8_t premultiplied, std::uint8_t alpha,
|
||||
std::uint8_t background) {
|
||||
return static_cast<std::uint8_t>(
|
||||
@@ -26,29 +17,17 @@ std::uint8_t flatten(std::uint8_t premultiplied, std::uint8_t alpha,
|
||||
|
||||
} // namespace
|
||||
|
||||
std::string encode_pixel_frame(Image_View image, Color background) {
|
||||
std::string encode_pixel_frame(Image_View image, std::uint64_t sequence, Color background) {
|
||||
if (image.empty() || image.format != Pixel_Format::Premultiplied_32 ||
|
||||
image.stride < image.width * static_cast<int>(sizeof(Pixel))) {
|
||||
return {};
|
||||
}
|
||||
const auto width = static_cast<std::size_t>(image.width);
|
||||
const auto height = static_cast<std::size_t>(image.height);
|
||||
if (width > (std::numeric_limits<std::size_t>::max() - pixel_frame_header_size) /
|
||||
(height * sizeof(Pixel))) {
|
||||
std::string frame = make_rgba8_pixel_frame(
|
||||
static_cast<std::uint32_t>(width), static_cast<std::uint32_t>(height), sequence);
|
||||
if (frame.empty())
|
||||
return {};
|
||||
}
|
||||
|
||||
const std::size_t pixel_bytes = width * height * sizeof(Pixel);
|
||||
std::string frame(pixel_frame_header_size + pixel_bytes, '\0');
|
||||
frame[0] = 'R';
|
||||
frame[1] = 'V';
|
||||
frame[2] = 'P';
|
||||
frame[3] = '1';
|
||||
write_u32_le(frame.data() + 4, static_cast<std::uint32_t>(image.width));
|
||||
write_u32_le(frame.data() + 8, static_cast<std::uint32_t>(image.height));
|
||||
write_u32_le(frame.data() + 12,
|
||||
static_cast<std::uint32_t>(image.width * static_cast<int>(sizeof(Pixel))));
|
||||
|
||||
auto* output = reinterpret_cast<std::uint32_t*>(frame.data() + pixel_frame_header_size);
|
||||
const std::uint32_t opaque_background =
|
||||
static_cast<std::uint32_t>(background.r) |
|
||||
@@ -111,35 +90,4 @@ std::string encode_pixel_frame(Image_View image, Color background) {
|
||||
return frame;
|
||||
}
|
||||
|
||||
std::string encode_rgba8_pixel_frame(const std::byte* pixels,
|
||||
std::uint32_t width,
|
||||
std::uint32_t height,
|
||||
std::size_t stride) {
|
||||
constexpr std::size_t bytes_per_pixel = 4;
|
||||
if (pixels == nullptr || width == 0 || height == 0)
|
||||
return {};
|
||||
if (width > std::numeric_limits<std::size_t>::max() / bytes_per_pixel)
|
||||
return {};
|
||||
const std::size_t row_bytes = static_cast<std::size_t>(width) * bytes_per_pixel;
|
||||
if (stride < row_bytes ||
|
||||
height > (std::numeric_limits<std::size_t>::max() - pixel_frame_header_size) /
|
||||
row_bytes)
|
||||
return {};
|
||||
|
||||
std::string frame(pixel_frame_header_size + row_bytes * height, '\0');
|
||||
frame[0] = 'R';
|
||||
frame[1] = 'V';
|
||||
frame[2] = 'P';
|
||||
frame[3] = '1';
|
||||
write_u32_le(frame.data() + 4, width);
|
||||
write_u32_le(frame.data() + 8, height);
|
||||
write_u32_le(frame.data() + 12, static_cast<std::uint32_t>(row_bytes));
|
||||
char* output = frame.data() + pixel_frame_header_size;
|
||||
for (std::uint32_t row = 0; row < height; ++row) {
|
||||
std::memcpy(output + static_cast<std::size_t>(row) * row_bytes,
|
||||
pixels + static_cast<std::size_t>(row) * stride, row_bytes);
|
||||
}
|
||||
return frame;
|
||||
}
|
||||
|
||||
} // namespace renderive::web
|
||||
|
||||
Reference in New Issue
Block a user