@amazon-devices/expo-image 2.0.9000000000 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CMakeLists.txt +80 -58
- package/README.kepler.md +1 -0
- package/build/ExpoImageModules.kepler.d.ts.map +1 -1
- package/build/ExpoImageModules.kepler.js +1 -1
- package/build/ExpoImageModules.kepler.js.map +1 -1
- package/build/ImageViewNativeComponent.js +1 -1
- package/build/ImageViewNativeComponent.js.map +1 -1
- package/kepler/AutoLinkInit.cpp +17 -0
- package/kepler/Constants.h +21 -0
- package/kepler/ExpoImage/ExpoImageTurboModule.cpp +148 -0
- package/kepler/ExpoImage/ExpoImageTurboModule.h +41 -0
- package/kepler/ExpoImage/PrefetchListener.cpp +45 -0
- package/kepler/ExpoImage/PrefetchListener.h +40 -0
- package/kepler/ExpoImageComponent/AccessibilityDelegate.cpp +33 -0
- package/kepler/ExpoImageComponent/AccessibilityDelegate.h +30 -0
- package/kepler/ExpoImageComponent/ExpoImageComponentViewManager.cpp +132 -0
- package/kepler/ExpoImageComponent/ExpoImageComponentViewManager.h +66 -0
- package/kepler/ExpoImageComponent/ExpoImageStore.h +102 -0
- package/kepler/ExpoImageComponent/ExpoImageView.cpp +556 -0
- package/kepler/ExpoImageComponent/ExpoImageView.h +186 -0
- package/kepler/ExpoImageComponent/HashImageDecoder.cpp +91 -0
- package/kepler/ExpoImageComponent/HashImageDecoder.h +18 -0
- package/kepler/ExpoImageComponent/ImageLoadListeners.cpp +73 -0
- package/kepler/ExpoImageComponent/ImageLoadListeners.h +52 -0
- package/kepler/ExpoImageComponent/TransitionAnimator.cpp +113 -0
- package/kepler/ExpoImageComponent/TransitionAnimator.h +32 -0
- package/kepler/ImageSourceInfo.h +21 -0
- package/kepler/ViewManagerFactory.cpp +36 -0
- package/kepler/ViewManagerFactory.h +29 -0
- package/kepler/blurhash/common.h +11 -10
- package/kepler/blurhash/decode.cpp +26 -16
- package/kepler/contentposition/ImageContentPosition.cpp +50 -69
- package/kepler/contentposition/ImageContentPosition.h +36 -26
- package/kepler/enums/ImageContentFit.h +47 -15
- package/kepler/enums/ImagePriority.h +12 -13
- package/kepler/test/blurhash/decode.cpp +36 -27
- package/kepler/test/contentposition/ImageContentPosition.cpp +70 -76
- package/kepler/test/thumbhash/decode.cpp +18 -10
- package/kepler/test/utils/Base64.cpp +73 -0
- package/kepler/test/utils/ColorUtils.cpp +53 -0
- package/kepler/test/utils/SourceSelection.cpp +87 -0
- package/kepler/thumbhash/decode.cpp +7 -16
- package/kepler/utils/Base64.cpp +85 -0
- package/kepler/utils/Base64.h +36 -0
- package/kepler/utils/ColorUtils.h +26 -0
- package/kepler/utils/SourceSelection.cpp +80 -0
- package/kepler/utils/SourceSelection.h +65 -0
- package/lib/aarch64-release/com.amazon.kepler.uitoolkit.react.expoimageapp.so +0 -0
- package/lib/aarch64-release/libexpo-image-3.so +0 -0
- package/lib/armv7-release/com.amazon.kepler.uitoolkit.react.expoimageapp.so +0 -0
- package/lib/armv7-release/libexpo-image-3.so +0 -0
- package/lib/x86_64-release/com.amazon.kepler.uitoolkit.react.expoimageapp.so +0 -0
- package/lib/x86_64-release/libexpo-image-3.so +0 -0
- package/package.json +1 -1
- package/react-native.config.js +12 -4
- package/src/ExpoImageModules.kepler.ts +1 -1
- package/src/ImageViewNativeComponent.ts +1 -1
- package/kepler/ExpoImage.cpp +0 -63
- package/kepler/ExpoImage.h +0 -29
- package/kepler/ExpoImageCacheHandler.cpp +0 -15
- package/kepler/ExpoImageCacheHandler.h +0 -28
- package/kepler/ExpoImageComponent.cpp +0 -579
- package/kepler/ExpoImageComponent.h +0 -199
- package/kepler/ImageWrapper/BlurhashImageWrapper.cpp +0 -37
- package/kepler/ImageWrapper/BlurhashImageWrapper.h +0 -23
- package/kepler/ImageWrapper/CacheImageWrapper.cpp +0 -80
- package/kepler/ImageWrapper/CacheImageWrapper.h +0 -41
- package/kepler/ImageWrapper/HashImageWrapper.cpp +0 -21
- package/kepler/ImageWrapper/HashImageWrapper.h +0 -22
- package/kepler/ImageWrapper/ImageWrapper.cpp +0 -24
- package/kepler/ImageWrapper/ImageWrapper.h +0 -33
- package/kepler/ImageWrapper/LocalImageWrapper.cpp +0 -61
- package/kepler/ImageWrapper/LocalImageWrapper.h +0 -30
- package/kepler/ImageWrapper/ThumbhashImageWrapper.cpp +0 -33
- package/kepler/ImageWrapper/ThumbhashImageWrapper.h +0 -20
- package/kepler/KeplerImageViewComponent.h +0 -64
- package/kepler/KeplerInit.cpp +0 -35
- package/kepler/managers/ExpoImageManager.cpp +0 -38
- package/kepler/managers/ExpoImageManager.h +0 -23
- package/kepler/test/ExpoImage.cpp +0 -73
- package/kepler/test/ExpoImageComponent.cpp +0 -304
- package/kepler/test/managers/ExpoImageManager.cpp +0 -39
- package/kepler/test/utils/LoaderDelegate.cpp +0 -130
- package/kepler/utils/PlaceholderImageLoaderDelegate.cpp +0 -26
- package/kepler/utils/PlaceholderImageLoaderDelegate.h +0 -26
- package/kepler/utils/PrefetchImageLoaderDelegate.cpp +0 -55
- package/kepler/utils/PrefetchImageLoaderDelegate.h +0 -35
- package/kepler/utils/SourceImageLoaderDelegate.cpp +0 -47
- package/kepler/utils/SourceImageLoaderDelegate.h +0 -42
- package/kepler/utils/SourceImageLoaderDelegateEmitter.cpp +0 -15
- package/kepler/utils/SourceImageLoaderDelegateEmitter.h +0 -28
- package/kepler-compatibility.json +0 -6
package/kepler/blurhash/common.h
CHANGED
|
@@ -11,22 +11,23 @@
|
|
|
11
11
|
|
|
12
12
|
#include <cmath>
|
|
13
13
|
|
|
14
|
-
int linearTosRGB(float value) {
|
|
14
|
+
inline int linearTosRGB(float value) {
|
|
15
15
|
float v = fmaxf(0, fminf(1, value));
|
|
16
|
-
if (v <= 0.0031308)
|
|
16
|
+
if (v <= 0.0031308) {
|
|
17
17
|
return v * 12.92 * 255 + 0.5;
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return (1.055 * powf(v, 1 / 2.4) - 0.055) * 255 + 0.5;
|
|
20
21
|
}
|
|
21
22
|
|
|
22
|
-
float sRGBToLinear(int value) {
|
|
23
|
-
float v = (
|
|
24
|
-
if (v <= 0.04045)
|
|
23
|
+
inline float sRGBToLinear(int value) {
|
|
24
|
+
float v = static_cast<float>(value) / 255;
|
|
25
|
+
if (v <= 0.04045) {
|
|
25
26
|
return v / 12.92;
|
|
26
|
-
|
|
27
|
-
|
|
27
|
+
}
|
|
28
|
+
return powf((v + 0.055) / 1.055, 2.4);
|
|
28
29
|
}
|
|
29
30
|
|
|
30
|
-
float signPow(float value, float exp) {
|
|
31
|
+
inline float signPow(float value, float exp) {
|
|
31
32
|
return copysignf(powf(fabsf(value), exp), value);
|
|
32
33
|
}
|
|
@@ -7,6 +7,10 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
// Source: https://github.com/woltapp/blurhash/blob/master/C/decode.c
|
|
10
|
+
|
|
11
|
+
#include <vector>
|
|
12
|
+
#include <array>
|
|
13
|
+
|
|
10
14
|
#include "decode.h"
|
|
11
15
|
|
|
12
16
|
#include <unordered_map>
|
|
@@ -66,7 +70,7 @@ int decodeToInt(const std::string& string, int start, int end) {
|
|
|
66
70
|
|
|
67
71
|
Size getImageSize(const std::string& blurhash) {
|
|
68
72
|
int sizeFlag = decodeToInt(blurhash, 0); // Get size from first character
|
|
69
|
-
int numY = (
|
|
73
|
+
int numY = static_cast<int>(floorf(sizeFlag / 9)) + 1;
|
|
70
74
|
int numX = (sizeFlag % 9) + 1;
|
|
71
75
|
|
|
72
76
|
return Size{numY, numX};
|
|
@@ -79,8 +83,7 @@ bool isValidBlurhash(const std::string& blurhash) {
|
|
|
79
83
|
if (hashLength < MINIMAL_HASH_LENGTH) return false;
|
|
80
84
|
auto size = getImageSize(blurhash);
|
|
81
85
|
|
|
82
|
-
|
|
83
|
-
return true;
|
|
86
|
+
return hashLength == 4 + 2 * size.x * size.y;
|
|
84
87
|
}
|
|
85
88
|
|
|
86
89
|
Color decodeDC(int value) {
|
|
@@ -97,9 +100,9 @@ Color decodeAC(int value, float maximumValue) {
|
|
|
97
100
|
int quantB = (int) value % 19;
|
|
98
101
|
|
|
99
102
|
return std::make_tuple(
|
|
100
|
-
signPow(((
|
|
101
|
-
signPow(((
|
|
102
|
-
signPow(((
|
|
103
|
+
signPow((static_cast<float>(quantR) - 9) / 9, 2.0) * maximumValue,
|
|
104
|
+
signPow((static_cast<float>(quantG) - 9) / 9, 2.0) * maximumValue,
|
|
105
|
+
signPow((static_cast<float>(quantB) - 9) / 9, 2.0) * maximumValue);
|
|
103
106
|
}
|
|
104
107
|
|
|
105
108
|
int decodeToArray(
|
|
@@ -117,21 +120,23 @@ int decodeToArray(
|
|
|
117
120
|
int quantizedMaxValue = decodeToInt(blurhash, 1);
|
|
118
121
|
if (quantizedMaxValue == -1) return -1;
|
|
119
122
|
|
|
120
|
-
float maxValue = (
|
|
123
|
+
float maxValue = (static_cast<float>(quantizedMaxValue + 1)) / 166;
|
|
121
124
|
|
|
122
|
-
int
|
|
123
|
-
float colors
|
|
125
|
+
int colorsSize = size.x * size.y;
|
|
126
|
+
std::vector<std::array<float, 3>> colors(colorsSize);
|
|
124
127
|
|
|
125
|
-
for (int iter = 0; iter <
|
|
126
|
-
float r = 0
|
|
128
|
+
for (int iter = 0; iter < colorsSize; ++iter) {
|
|
129
|
+
float r = 0;
|
|
130
|
+
float g = 0;
|
|
131
|
+
float b = 0;
|
|
127
132
|
if (iter == 0) {
|
|
128
133
|
int value = decodeToInt(blurhash, 2, 6);
|
|
129
|
-
if (value == -1) return -1;
|
|
134
|
+
if (value == -1) { return -1;}
|
|
130
135
|
std::tie(r, g, b) = decodeDC(value);
|
|
131
136
|
|
|
132
137
|
} else {
|
|
133
138
|
int value = decodeToInt(blurhash, 4 + iter * 2, 6 + iter * 2);
|
|
134
|
-
if (value == -1) return -1;
|
|
139
|
+
if (value == -1) { return -1;}
|
|
135
140
|
std::tie(r, g, b) = decodeAC(value, maxValue * punch);
|
|
136
141
|
}
|
|
137
142
|
colors[iter][0] = r;
|
|
@@ -140,11 +145,15 @@ int decodeToArray(
|
|
|
140
145
|
}
|
|
141
146
|
|
|
142
147
|
int bytesPerRow = width * nChannels;
|
|
143
|
-
int intR = 0
|
|
148
|
+
int intR = 0;
|
|
149
|
+
int intG = 0;
|
|
150
|
+
int intB = 0;
|
|
144
151
|
|
|
145
152
|
for (int y = 0; y < height; ++y) {
|
|
146
153
|
for (int x = 0; x < width; ++x) {
|
|
147
|
-
float r = 0
|
|
154
|
+
float r = 0;
|
|
155
|
+
float g = 0;
|
|
156
|
+
float b = 0;
|
|
148
157
|
|
|
149
158
|
for (int j = 0; j < size.y; ++j) {
|
|
150
159
|
for (int i = 0; i < size.x; ++i) {
|
|
@@ -164,9 +173,10 @@ int decodeToArray(
|
|
|
164
173
|
pixelArray[nChannels * x + 1 + y * bytesPerRow] = clampToUByte(intG);
|
|
165
174
|
pixelArray[nChannels * x + 2 + y * bytesPerRow] = clampToUByte(intB);
|
|
166
175
|
|
|
167
|
-
if (nChannels == 4)
|
|
176
|
+
if (nChannels == 4) {
|
|
168
177
|
pixelArray[nChannels * x + 3 + y * bytesPerRow] =
|
|
169
178
|
255; // If nChannels=4, treat each pixel as RGBA instead of RGB
|
|
179
|
+
}
|
|
170
180
|
}
|
|
171
181
|
}
|
|
172
182
|
|
|
@@ -1,86 +1,67 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright (c) 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
3
|
-
*
|
|
4
|
-
* PROPRIETARY/CONFIDENTIAL
|
|
5
|
-
*
|
|
6
|
-
* Use is subject to license terms.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
1
|
#include "ImageContentPosition.h"
|
|
10
2
|
|
|
11
|
-
#include <
|
|
3
|
+
#include <apmf/iface/com/amazon/kepler/uitoolkit/react/JsType.h>
|
|
4
|
+
|
|
5
|
+
#include "../utils/SourceSelection.h"
|
|
6
|
+
|
|
7
|
+
namespace expoimage {
|
|
12
8
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
bool isReverse = false) {
|
|
9
|
+
using apmf::iface::com::amazon::kepler::uitoolkit::react::JsType;
|
|
10
|
+
|
|
11
|
+
namespace {
|
|
12
|
+
|
|
13
|
+
float calcTranslation(float value, float imageVal, float viewVal, bool isPercentage, bool isReverse) {
|
|
19
14
|
if (isPercentage) {
|
|
20
|
-
float
|
|
21
|
-
return (
|
|
15
|
+
float pct = isReverse ? 100.0f - value : value;
|
|
16
|
+
return (pct / 100.0f) * (viewVal - imageVal);
|
|
22
17
|
}
|
|
23
|
-
|
|
24
|
-
return isReverse ? viewRefValue - imageRefValue - value : value;
|
|
18
|
+
return isReverse ? viewVal - imageVal - value : value;
|
|
25
19
|
}
|
|
26
20
|
|
|
27
|
-
float
|
|
28
|
-
|
|
29
|
-
const volta::graphics::Size& imageRect,
|
|
30
|
-
const volta::graphics::Size& viewRect,
|
|
31
|
-
bool isPercentage = false,
|
|
32
|
-
bool isReverse = false) {
|
|
33
|
-
return calcTranslation(value, imageRect.width(), viewRect.width(), isPercentage, isReverse);
|
|
21
|
+
float calcX(float value, const Size& imageRect, const Size& viewRect, bool isPercentage, bool isReverse) {
|
|
22
|
+
return calcTranslation(value, imageRect.width, viewRect.width, isPercentage, isReverse);
|
|
34
23
|
}
|
|
35
24
|
|
|
36
|
-
float
|
|
37
|
-
|
|
38
|
-
const volta::graphics::Size& imageRect,
|
|
39
|
-
const volta::graphics::Size& viewRect,
|
|
40
|
-
bool isPercentage = false,
|
|
41
|
-
bool isReverse = false) {
|
|
42
|
-
return calcTranslation(value, imageRect.height(), viewRect.height(), isPercentage, isReverse);
|
|
25
|
+
float calcY(float value, const Size& imageRect, const Size& viewRect, bool isPercentage, bool isReverse) {
|
|
26
|
+
return calcTranslation(value, imageRect.height, viewRect.height, isPercentage, isReverse);
|
|
43
27
|
}
|
|
44
28
|
|
|
45
|
-
|
|
29
|
+
} // namespace
|
|
46
30
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
std::optional<float> ImageContentPositionValue::calcOffset(
|
|
52
|
-
bool isReverse,
|
|
53
|
-
const volta::graphics::Size& imageRect,
|
|
54
|
-
const volta::graphics::Size& viewRect,
|
|
55
|
-
std::function<float(float, const volta::graphics::Size&, const volta::graphics::Size&, bool, bool)>
|
|
56
|
-
calcAxisOffset) {
|
|
57
|
-
return value_ ? calcAxisOffset(value_.value(), imageRect, viewRect, isPercentage_, isReverse) : value_;
|
|
31
|
+
float ImageContentPosition::offsetX(const Size& imageRect, const Size& viewRect) const {
|
|
32
|
+
return left_.calcOffset(false, imageRect, viewRect, &calcX)
|
|
33
|
+
.value_or(right_.calcOffset(true, imageRect, viewRect, &calcX)
|
|
34
|
+
.value_or(calcX(50.0f, imageRect, viewRect, true, false)));
|
|
58
35
|
}
|
|
59
36
|
|
|
60
|
-
ImageContentPosition::
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
left_(ImageContentPositionValue()) {}
|
|
65
|
-
|
|
66
|
-
ImageContentPosition::ImageContentPosition(
|
|
67
|
-
ImageContentPositionValue top,
|
|
68
|
-
ImageContentPositionValue bottom,
|
|
69
|
-
ImageContentPositionValue right,
|
|
70
|
-
ImageContentPositionValue left) :
|
|
71
|
-
top_(top),
|
|
72
|
-
bottom_(bottom),
|
|
73
|
-
right_(right),
|
|
74
|
-
left_(left) {}
|
|
75
|
-
|
|
76
|
-
float ImageContentPosition::offsetX(const volta::graphics::Size& imageRect, const volta::graphics::Size& viewRect) {
|
|
77
|
-
return left_.calcOffset(false, imageRect, viewRect, &calcXTranslation)
|
|
78
|
-
.value_or(right_.calcOffset(true, imageRect, viewRect, &calcXTranslation)
|
|
79
|
-
.value_or(calcXTranslation(50.0f, imageRect, viewRect, true)));
|
|
37
|
+
float ImageContentPosition::offsetY(const Size& imageRect, const Size& viewRect) const {
|
|
38
|
+
return top_.calcOffset(false, imageRect, viewRect, &calcY)
|
|
39
|
+
.value_or(bottom_.calcOffset(true, imageRect, viewRect, &calcY)
|
|
40
|
+
.value_or(calcY(50.0f, imageRect, viewRect, true, false)));
|
|
80
41
|
}
|
|
81
42
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
43
|
+
ImageContentPositionValue parsePositionValue(View<IJsObject> obj, const std::string& key) {
|
|
44
|
+
ImageContentPositionValue result;
|
|
45
|
+
auto keys = obj->getAllKeys();
|
|
46
|
+
if (!hasKey(keys, key)) return result;
|
|
47
|
+
auto type = obj->getElementValueType(key);
|
|
48
|
+
if (type.value == JsType::STRING.value) {
|
|
49
|
+
std::string val = obj->getString(key);
|
|
50
|
+
if (!val.empty() && val.back() == '%') {
|
|
51
|
+
try {
|
|
52
|
+
result.value = std::stof(val);
|
|
53
|
+
result.isPercentage = true;
|
|
54
|
+
} catch (...) {
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
} else if (type.value == JsType::DOUBLE.value) {
|
|
58
|
+
result.value = static_cast<float>(obj->getDouble(key));
|
|
59
|
+
result.isPercentage = false;
|
|
60
|
+
} else if (type.value == JsType::INT.value) {
|
|
61
|
+
result.value = static_cast<float>(obj->getInt(key));
|
|
62
|
+
result.isPercentage = false;
|
|
63
|
+
}
|
|
64
|
+
return result;
|
|
86
65
|
}
|
|
66
|
+
|
|
67
|
+
} // namespace expoimage
|
|
@@ -7,42 +7,52 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
#pragma once
|
|
10
|
-
|
|
10
|
+
|
|
11
|
+
#include <apmf/iface/com/amazon/kepler/uitoolkit/graphics/Size.h>
|
|
12
|
+
#include <apmf/iface/com/amazon/kepler/uitoolkit/react/IJsObject.h>
|
|
11
13
|
|
|
12
14
|
#include <functional>
|
|
13
15
|
#include <optional>
|
|
14
16
|
#include <string>
|
|
15
17
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
namespace expoimage {
|
|
19
|
+
|
|
20
|
+
using Size = apmf::iface::com::amazon::kepler::uitoolkit::graphics::Size;
|
|
21
|
+
using apmf::detail::View;
|
|
22
|
+
using apmf::iface::com::amazon::kepler::uitoolkit::react::IJsObject;
|
|
23
|
+
|
|
24
|
+
struct ImageContentPositionValue {
|
|
25
|
+
std::optional<float> value;
|
|
26
|
+
bool isPercentage{true};
|
|
27
|
+
|
|
28
|
+
ImageContentPositionValue() = default;
|
|
29
|
+
ImageContentPositionValue(float v, bool pct) : value(v), isPercentage(pct) {}
|
|
30
|
+
|
|
22
31
|
std::optional<float> calcOffset(
|
|
23
|
-
bool isReverse,
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
32
|
+
bool isReverse, const Size& imageSize, const Size& viewSize,
|
|
33
|
+
std::function<float(float, const Size&, const Size&, bool, bool)> calc) const {
|
|
34
|
+
if (value) {
|
|
35
|
+
return calc(*value, imageSize, viewSize, isPercentage, isReverse);
|
|
36
|
+
}
|
|
37
|
+
return std::nullopt;
|
|
38
|
+
}
|
|
28
39
|
};
|
|
29
40
|
|
|
30
41
|
class ImageContentPosition {
|
|
31
42
|
public:
|
|
32
|
-
ImageContentPosition();
|
|
43
|
+
ImageContentPosition() = default;
|
|
33
44
|
ImageContentPosition(
|
|
34
|
-
ImageContentPositionValue top,
|
|
35
|
-
ImageContentPositionValue
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
float offsetX(const
|
|
39
|
-
float offsetY(const
|
|
40
|
-
|
|
41
|
-
#ifndef UNIT_TEST
|
|
45
|
+
ImageContentPositionValue top, ImageContentPositionValue bottom,
|
|
46
|
+
ImageContentPositionValue right, ImageContentPositionValue left)
|
|
47
|
+
: top_(top), bottom_(bottom), right_(right), left_(left) {}
|
|
48
|
+
|
|
49
|
+
float offsetX(const Size& imageRect, const Size& viewRect) const;
|
|
50
|
+
float offsetY(const Size& imageRect, const Size& viewRect) const;
|
|
51
|
+
|
|
42
52
|
private:
|
|
43
|
-
|
|
44
|
-
ImageContentPositionValue top_;
|
|
45
|
-
ImageContentPositionValue bottom_;
|
|
46
|
-
ImageContentPositionValue right_;
|
|
47
|
-
ImageContentPositionValue left_;
|
|
53
|
+
ImageContentPositionValue top_, bottom_, right_, left_;
|
|
48
54
|
};
|
|
55
|
+
|
|
56
|
+
ImageContentPositionValue parsePositionValue(View<IJsObject> obj, const std::string& key);
|
|
57
|
+
|
|
58
|
+
} // namespace expoimage
|
|
@@ -1,17 +1,49 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright (c) 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
3
|
-
*
|
|
4
|
-
* PROPRIETARY/CONFIDENTIAL
|
|
5
|
-
*
|
|
6
|
-
* Use is subject to license terms.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
1
|
#pragma once
|
|
10
2
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
3
|
+
#include <apmf/iface/com/amazon/kepler/uitoolkit/graphics/Size.h>
|
|
4
|
+
#include <apmf/iface/com/amazon/kepler/uitoolkit/view/Fit.h>
|
|
5
|
+
|
|
6
|
+
#include <string>
|
|
7
|
+
|
|
8
|
+
namespace expoimage {
|
|
9
|
+
|
|
10
|
+
using apmf::iface::com::amazon::kepler::uitoolkit::view::Fit;
|
|
11
|
+
|
|
12
|
+
enum class ImageContentFit { Cover, Contain, Fill, None, ScaleDown };
|
|
13
|
+
|
|
14
|
+
inline ImageContentFit parseContentFit(const std::string& value, ImageContentFit defaultFit = ImageContentFit::Cover) {
|
|
15
|
+
if (value == "contain") return ImageContentFit::Contain;
|
|
16
|
+
if (value == "fill") return ImageContentFit::Fill;
|
|
17
|
+
if (value == "scale-down") return ImageContentFit::ScaleDown;
|
|
18
|
+
if (value == "none") return ImageContentFit::None;
|
|
19
|
+
if (value == "cover") return ImageContentFit::Cover;
|
|
20
|
+
return defaultFit;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** Maps ImageContentFit to stable Fit enum. All modes have direct platform support. */
|
|
24
|
+
inline Fit toFit(ImageContentFit contentFit) {
|
|
25
|
+
switch (contentFit) {
|
|
26
|
+
case ImageContentFit::Cover: return Fit::COVER;
|
|
27
|
+
case ImageContentFit::Contain: return Fit::CONTAIN;
|
|
28
|
+
case ImageContentFit::Fill: return Fit::STRETCH;
|
|
29
|
+
case ImageContentFit::ScaleDown: return Fit::SCALE_DOWN;
|
|
30
|
+
case ImageContentFit::None: return Fit::NONE;
|
|
31
|
+
}
|
|
32
|
+
return Fit::COVER;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
inline Fit resolveNativeFit(
|
|
36
|
+
ImageContentFit fit,
|
|
37
|
+
bool allowDownscaling,
|
|
38
|
+
apmf::iface::com::amazon::kepler::uitoolkit::graphics::Size imageSize,
|
|
39
|
+
apmf::iface::com::amazon::kepler::uitoolkit::graphics::Size viewSize) {
|
|
40
|
+
if (!allowDownscaling) return Fit::NONE;
|
|
41
|
+
if (fit != ImageContentFit::ScaleDown) return toFit(fit);
|
|
42
|
+
const bool imageSizeKnown = imageSize.width > 0 && imageSize.height > 0;
|
|
43
|
+
if (!imageSizeKnown) return Fit::CONTAIN;
|
|
44
|
+
const bool imageFitsInView =
|
|
45
|
+
imageSize.width <= viewSize.width && imageSize.height <= viewSize.height;
|
|
46
|
+
return imageFitsInView ? Fit::NONE : Fit::CONTAIN;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
} // namespace expoimage
|
|
@@ -1,17 +1,16 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright (c) 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
3
|
-
*
|
|
4
|
-
* PROPRIETARY/CONFIDENTIAL
|
|
5
|
-
*
|
|
6
|
-
* Use is subject to license terms.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
1
|
#pragma once
|
|
10
2
|
|
|
11
3
|
#include <cstdint>
|
|
4
|
+
#include <string>
|
|
5
|
+
|
|
6
|
+
namespace expoimage {
|
|
7
|
+
|
|
8
|
+
enum class ImagePriority : uint8_t { Low = 1, Normal = 2, High = 3 };
|
|
9
|
+
|
|
10
|
+
inline ImagePriority parsePriority(const std::string& value) {
|
|
11
|
+
if (value == "low") return ImagePriority::Low;
|
|
12
|
+
if (value == "high") return ImagePriority::High;
|
|
13
|
+
return ImagePriority::Normal;
|
|
14
|
+
}
|
|
12
15
|
|
|
13
|
-
|
|
14
|
-
Low,
|
|
15
|
-
Normal,
|
|
16
|
-
High
|
|
17
|
-
};
|
|
16
|
+
} // namespace expoimage
|
|
@@ -1,39 +1,48 @@
|
|
|
1
1
|
#include "../../blurhash/decode.h"
|
|
2
2
|
|
|
3
|
-
#include <gmock/gmock-actions.h>
|
|
4
|
-
#include <gmock/gmock.h>
|
|
5
3
|
#include <gtest/gtest.h>
|
|
6
4
|
|
|
7
|
-
|
|
5
|
+
namespace expoimage {
|
|
6
|
+
namespace {
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
std::string validBlurHash = "LGF5]+Yk^6#M@-5c,1J5@[or[Q6.";
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
TEST(BlurhashDecode, IsValidBlurhashAcceptsWellFormed) {
|
|
9
|
+
const std::string validBlurHash = "LGF5]+Yk^6#M@-5c,1J5@[or[Q6.";
|
|
10
|
+
EXPECT_TRUE(isValidBlurhash(validBlurHash));
|
|
11
|
+
}
|
|
13
12
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
TEST(BlurhashDecode, IsValidBlurhashRejectsGarbage) {
|
|
14
|
+
EXPECT_FALSE(isValidBlurhash("some invalid blurhash"));
|
|
15
|
+
EXPECT_FALSE(isValidBlurhash(""));
|
|
16
|
+
}
|
|
18
17
|
|
|
19
|
-
|
|
18
|
+
TEST(BlurhashDecode, DecodeProducesExpectedBufferSize) {
|
|
19
|
+
const std::string nearBlackHash = "L0006Mp2p2p2fRfRfRfRfQfQfQfQ";
|
|
20
|
+
const int channels = 3;
|
|
21
|
+
const int width = 32;
|
|
22
|
+
const int height = 32;
|
|
20
23
|
|
|
21
|
-
|
|
22
|
-
int bytesPerRow = 32 * channels;
|
|
24
|
+
constexpr int kNearBlackThreshold = 64;
|
|
23
25
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
for (int ch = 0; i < channels; i++) {
|
|
27
|
-
int part = decoded.get()[channels * j + ch + i * bytesPerRow];
|
|
28
|
-
// expect each channel to be close to 0
|
|
29
|
-
CHECK(part < 10);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}
|
|
26
|
+
auto decoded = decodeBlurhash(nearBlackHash, width, height, 1, channels);
|
|
27
|
+
ASSERT_NE(decoded, nullptr);
|
|
34
28
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
29
|
+
const int totalBytes = width * height * channels;
|
|
30
|
+
int maxByte = 0;
|
|
31
|
+
for (int i = 0; i < totalBytes; ++i) {
|
|
32
|
+
int byte = decoded.get()[i];
|
|
33
|
+
if (byte > maxByte) maxByte = byte;
|
|
38
34
|
}
|
|
35
|
+
EXPECT_LT(maxByte, kNearBlackThreshold)
|
|
36
|
+
<< "Decoded buffer unexpectedly bright for near-black hash; "
|
|
37
|
+
"brightest byte was "
|
|
38
|
+
<< maxByte;
|
|
39
39
|
}
|
|
40
|
+
|
|
41
|
+
TEST(BlurhashDecode, DecodeReturnsNonNullForValidHash) {
|
|
42
|
+
const std::string validBlurHash = "LGF5]+Yk^6#M@-5c,1J5@[or[Q6.";
|
|
43
|
+
auto decoded = decodeBlurhash(validBlurHash, 16, 16, 1, 3);
|
|
44
|
+
EXPECT_NE(decoded, nullptr);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
} // namespace
|
|
48
|
+
} // namespace expoimage
|