载入中...
搜索中...
未找到
ImageScale.cpp
浏览该文件的文档.
1#include "image/ImageData.h"
2
3#include "common/Diagnostic.h"
4
5#include <cmath>
6#include <limits>
7
8namespace eve::image {
9
11 const auto invalid = [](const char* message) {
13 };
14 if (newWidth <= 0 || newHeight <= 0)
15 return invalid("Pcg texture scale requires positive destination dimensions");
17 return invalid("Pcg texture scale requires point or bilinear filtering");
18 if (getWidth() <= 0 || getHeight() <= 0)
19 return invalid("Pcg texture scale requires a non-empty source image");
20 if (filter == ImageScaleFilter::Bilinear && (getWidth() < 2 || getHeight() < 2))
21 return invalid("Pcg bilinear scale requires both source dimensions to be at least two");
22 const auto count = std::uint64_t(newWidth) * std::uint64_t(newHeight);
23 if (count > std::uint64_t(std::numeric_limits<int>::max()))
24 return invalid("Pcg texture scale destination exceeds the supported pixel count");
25
26 ImageData candidate(newWidth, newHeight, getFormat());
27 const float ratioX = filter == ImageScaleFilter::Bilinear
28 ? float(getWidth() - 1) / float(newWidth)
29 : float(getWidth()) / float(newWidth);
30 const float ratioY = filter == ImageScaleFilter::Bilinear
31 ? float(getHeight() - 1) / float(newHeight)
32 : float(getHeight()) / float(newHeight);
33 const auto lerp = [](const Colorf& first, const Colorf& second, float amount) {
34 return Colorf{first.r + (second.r - first.r) * amount, first.g + (second.g - first.g) * amount,
35 first.b + (second.b - first.b) * amount, first.a + (second.a - first.a) * amount};
36 };
37 for (int y = 0; y < newHeight; ++y) {
39 const int sourceY = int(ratioY * float(y));
40 for (int x = 0; x < newWidth; ++x)
41 candidate.setPixel(x, y, getPixel(int(ratioX * float(x)), sourceY));
42 continue;
43 }
44 const float sourceY = float(y) * ratioY;
45 const int yFloor = int(std::floor(sourceY));
46 const float yLerp = sourceY - float(yFloor);
47 for (int x = 0; x < newWidth; ++x) {
48 const float sourceX = float(x) * ratioX;
49 const int xFloor = int(std::floor(sourceX));
50 const float xLerp = sourceX - float(xFloor);
51 const auto topLeft = getPixel(xFloor, yFloor);
52 const auto topRight = getPixel(xFloor + 1, yFloor);
53 const auto bottomLeft = getPixel(xFloor, yFloor + 1);
54 const auto bottomRight = getPixel(xFloor + 1, yFloor + 1);
55 const auto top = lerp(topLeft, topRight, xLerp);
56 const auto bottom = lerp(bottomLeft, bottomRight, xLerp);
57 candidate.setPixel(x, y, lerp(top, bottom, yLerp));
58 }
59 }
60 adopt(candidate);
61 return Result<int>::success(int(count));
62}
63
64} // namespace eve::image
SQInteger top
float y
Definition AnimClip.cpp:738
float x
Definition AnimClip.cpp:738
Stable, structured diagnostics shared by engine modules.
std::string message
std::int32_t second
std::int32_t first
std::string filter
std::uint32_t count
float sourceX
float bottom
static Diagnostic error(DiagnosticCode code, std::string message, std::string path={}, DiagnosticDetails details={}, std::string source={})
Construct an error diagnostic with the standard error severity.
Definition Diagnostic.h:125
Move-only operation result carrying either a value or Status.
Definition Result.h:155
static Result success(T value)
Construct a successful result owning value.
Definition Result.h:164
static Result failure(Status status)
Construct a failed result from a structured status.
Definition Result.h:175
Represents raw pixel data.
Definition ImageData.h:38
void getPixel(int x, int y, Colorf &c) const
Gets the pixel at location (x,y).
void setPixel(int x, int y, const Colorf &p)
Sets the pixel at location (x,y).
medialoader::Colorf Colorf
Definition ImageData.h:41
eve::Result< int > scalePcg(int newWidth, int newHeight, ImageScaleFilter filter)
Resize this image with Pcg ScaleTexture's exact point or bilinear coordinate mapping.
void adopt(eve::Resource &replacement) override
Replace this instance's pixels with replacement's (cache reload). The replacement is drained; its des...
Definition ImageData.cpp:62
std::string getFormat() const
ImageScaleFilter
Sampling modes used by Pcg-compatible in-place texture scaling.
Definition ImageData.h:26