Веб-сайт самохостера Lotigara

summaryrefslogtreecommitdiff
path: root/source/core
diff options
context:
space:
mode:
Diffstat (limited to 'source/core')
-rw-r--r--source/core/StarAssetPath.cpp13
-rw-r--r--source/core/StarDirectives.cpp42
-rw-r--r--source/core/StarDirectives.hpp6
-rw-r--r--source/core/StarImageProcessing.cpp7
-rw-r--r--source/core/StarImageProcessing.hpp6
-rw-r--r--source/core/StarStringView.cpp4
6 files changed, 57 insertions, 21 deletions
diff --git a/source/core/StarAssetPath.cpp b/source/core/StarAssetPath.cpp
index a99ecfa..cb607fb 100644
--- a/source/core/StarAssetPath.cpp
+++ b/source/core/StarAssetPath.cpp
@@ -39,11 +39,14 @@ AssetPath AssetPath::split(String const& path) {
// Sub-paths must immediately follow base paths and must start with a ':',
// after this point any further ':' characters are not special.
if (str[end] == ':') {
- size_t beg = end;
- end = str.find_first_of("?", beg);
- size_t len = end - beg - 1;
- if (len)
- components.subPath.emplace(str.substr(beg + 1, len));
+ size_t beg = end + 1;
+ if (beg != str.size()) {
+ end = str.find_first_of("?", beg);
+ if (end == NPos && beg + 1 != str.size())
+ components.subPath.emplace(str.substr(beg));
+ else if (size_t len = end - beg)
+ components.subPath.emplace(str.substr(beg, len));
+ }
}
if (end == NPos)
diff --git a/source/core/StarDirectives.cpp b/source/core/StarDirectives.cpp
index cac1eaf..a18951e 100644
--- a/source/core/StarDirectives.cpp
+++ b/source/core/StarDirectives.cpp
@@ -24,6 +24,14 @@ Directives::Entry::Entry(Entry const& other) {
length = other.length;
}
+ImageOperation const& Directives::Entry::loadOperation(Shared const& parent) const {
+ if (operation.is<NullImageOperation>()) {
+ try { operation = imageOperationFromString(string(parent)); }
+ catch (StarException const& e) { operation = ErrorImageOperation{ std::current_exception() }; }
+ }
+ return operation;
+}
+
StringView Directives::Entry::string(Shared const& parent) const {
StringView result = parent.string;
result = result.utf8().substr(begin, length);
@@ -54,6 +62,15 @@ Directives::Directives(const char* directives) {
parse(directives);
}
+void Directives::loadOperations() const {
+ if (!shared)
+ return;
+
+ MutexLocker lock(shared->mutex, true);
+ for (auto& entry : shared->entries)
+ entry.loadOperation(*shared);
+}
+
void Directives::parse(String&& directives) {
if (directives.empty())
return;
@@ -63,15 +80,19 @@ void Directives::parse(String&& directives) {
StringView prefix = "";
view.forEachSplitView("?", [&](StringView split, size_t beg, size_t end) {
if (!split.empty()) {
- try {
- ImageOperation operation = imageOperationFromString(split);
- newList.emplace_back(move(operation), beg, end);
- }
- catch (StarException const& e) {
- if (beg == 0)
+ if (beg == 0) {
+ try {
+ ImageOperation operation = imageOperationFromString(split);
+ newList.emplace_back(move(operation), beg, end);
+ }
+ catch (StarException const& e) {
prefix = split;
- else
- newList.emplace_back(ErrorImageOperation{ std::current_exception() }, beg, end);
+ return;
+ }
+ }
+ else {
+ ImageOperation operation = NullImageOperation();
+ newList.emplace_back(move(operation), beg, end);
}
}
});
@@ -259,10 +280,11 @@ inline Image DirectivesGroup::applyNewImage(Image const& image) const {
void DirectivesGroup::applyExistingImage(Image& image) const {
forEach([&](auto const& entry, Directives const& directives) {
- if (auto error = entry.operation.ptr<ErrorImageOperation>())
+ ImageOperation const& operation = entry.loadOperation(*directives.shared);
+ if (auto error = operation.ptr<ErrorImageOperation>())
std::rethrow_exception(error->exception);
else
- processImageOperation(entry.operation, image);
+ processImageOperation(operation, image);
});
}
diff --git a/source/core/StarDirectives.hpp b/source/core/StarDirectives.hpp
index 8af2f51..f841373 100644
--- a/source/core/StarDirectives.hpp
+++ b/source/core/StarDirectives.hpp
@@ -5,6 +5,7 @@
#include "StarHash.hpp"
#include "StarDataStream.hpp"
#include "StarStringView.hpp"
+#include "StarThread.hpp"
namespace Star {
@@ -17,10 +18,11 @@ class Directives {
public:
struct Shared;
struct Entry {
- ImageOperation operation;
+ mutable ImageOperation operation;
size_t begin;
size_t length;
+ ImageOperation const& loadOperation(Shared const& parent) const;
inline StringView string(Shared const& parent) const;
Entry(ImageOperation&& newOperation, size_t begin, size_t end);
Entry(ImageOperation const& newOperation, size_t begin, size_t end);
@@ -32,6 +34,7 @@ public:
String string;
StringView prefix;
size_t hash = 0;
+ mutable Mutex mutex;
bool empty() const;
Shared(List<Entry>&& givenEntries, String&& givenString, StringView givenPrefix);
@@ -42,6 +45,7 @@ public:
Directives(String&& directives);
Directives(const char* directives);
+ void loadOperations() const;
void parse(String&& directives);
String string() const;
StringView prefix() const;
diff --git a/source/core/StarImageProcessing.cpp b/source/core/StarImageProcessing.cpp
index 4dfcf8a..e95a13f 100644
--- a/source/core/StarImageProcessing.cpp
+++ b/source/core/StarImageProcessing.cpp
@@ -198,8 +198,11 @@ ImageOperation imageOperationFromString(StringView string) {
else if (hexLen == 8) {
hexDecode(hexPtr, 8, c, 4);
}
- else
- throw ImageOperationException(strf("Improper size for hex string '%s' in imageOperationFromString", StringView(hexPtr, hexLen)), false);
+ else if (!which || (ptr != end && ++ptr != end))
+ throw ImageOperationException(strf("Improper size for hex string '%s' in imageOperationFromString", StringView(hexPtr, hexLen)), false);
+ else // we're in A of A=B. In vanilla only A=B pairs are evaluated, so only throw an exception if B is also there.
+ return move(operation);
+
if (which = !which)
operation.colorReplaceMap[*(Vec4B*)&a] = *(Vec4B*)&b;
diff --git a/source/core/StarImageProcessing.hpp b/source/core/StarImageProcessing.hpp
index 0b78408..ed3319b 100644
--- a/source/core/StarImageProcessing.hpp
+++ b/source/core/StarImageProcessing.hpp
@@ -18,6 +18,10 @@ Image scaleBicubic(Image const& srcImage, Vec2F const& scale);
StringList colorDirectivesFromConfig(JsonArray const& directives);
String paletteSwapDirectivesFromConfig(Json const& swaps);
+struct NullImageOperation {
+
+};
+
struct ErrorImageOperation {
std::exception_ptr exception;
};
@@ -133,7 +137,7 @@ struct FlipImageOperation {
Mode mode;
};
-typedef Variant<ErrorImageOperation, HueShiftImageOperation, SaturationShiftImageOperation, BrightnessMultiplyImageOperation, FadeToColorImageOperation,
+typedef Variant<NullImageOperation, ErrorImageOperation, HueShiftImageOperation, SaturationShiftImageOperation, BrightnessMultiplyImageOperation, FadeToColorImageOperation,
ScanLinesImageOperation, SetColorImageOperation, ColorReplaceImageOperation, AlphaMaskImageOperation, BlendImageOperation,
MultiplyImageOperation, BorderImageOperation, ScaleImageOperation, CropImageOperation, FlipImageOperation> ImageOperation;
diff --git a/source/core/StarStringView.cpp b/source/core/StarStringView.cpp
index d0e0e07..1357404 100644
--- a/source/core/StarStringView.cpp
+++ b/source/core/StarStringView.cpp
@@ -127,7 +127,7 @@ void StringView::forEachSplitAnyView(StringView chars, SplitCallback callback) c
while (true) {
size_t end = m_view.find_first_of(chars.m_view, beg);
if (end == NPos) {
- callback(m_view.substr(beg), beg, end);
+ callback(m_view.substr(beg), beg, m_view.size() - beg);
break;
}
callback(m_view.substr(beg, end - beg), beg, end - beg);
@@ -143,7 +143,7 @@ void StringView::forEachSplitView(StringView pattern, SplitCallback callback) co
while (true) {
size_t end = m_view.find(pattern.m_view, beg);
if (end == NPos) {
- callback(m_view.substr(beg), beg, end);
+ callback(m_view.substr(beg), beg, m_view.size() - beg);
break;
}
callback(m_view.substr(beg, end - beg), beg, end - beg);