@react-native-ohos/react-native-blurhash 2.0.4-rc.4 → 2.1.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/harmony/blurhash/BuildProfile.ets +17 -0
- package/harmony/blurhash/index.ets +0 -2
- package/harmony/blurhash/oh-package.json5 +1 -1
- package/harmony/blurhash/src/main/cpp/Blurhash.cpp +78 -172
- package/harmony/blurhash/src/main/cpp/{Blurhash.h → Blurhash.hpp} +3 -6
- package/harmony/blurhash/src/main/cpp/BlurhashNode.cpp +12 -18
- package/harmony/blurhash/src/main/cpp/BlurhashNode.h +2 -3
- package/harmony/blurhash/src/main/cpp/BlurhashPackage.h +12 -23
- package/harmony/blurhash/src/main/cpp/BlurhashViewComponentInstance.cpp +82 -56
- package/harmony/blurhash/src/main/cpp/BlurhashViewComponentInstance.h +5 -8
- package/harmony/blurhash/src/main/cpp/BlurhashViewJSIBinder.h +7 -11
- package/harmony/blurhash/src/main/cpp/ComponentDescriptors.h +2 -4
- package/harmony/blurhash/src/main/cpp/EventEmitters.cpp +8 -9
- package/harmony/blurhash/src/main/cpp/EventEmitters.h +4 -4
- package/harmony/blurhash/src/main/cpp/Props.cpp +10 -11
- package/harmony/blurhash/src/main/cpp/Props.h +13 -19
- package/harmony/blurhash/src/main/cpp/RNBlurhashTurboModule.cpp +10 -16
- package/harmony/blurhash/src/main/cpp/RNBlurhashTurboModule.h +3 -3
- package/harmony/blurhash/src/main/cpp/ShadowNodes.cpp +2 -1
- package/harmony/blurhash/src/main/cpp/ShadowNodes.h +5 -5
- package/harmony/blurhash/src/main/cpp/SparseArray.cpp +4 -7
- package/harmony/blurhash/src/main/cpp/SparseArray.h +2 -2
- package/harmony/blurhash/src/main/cpp/napi_init.cpp +6 -5
- package/harmony/blurhash/src/main/cpp/types/libblurhash/Index.d.ts +1 -1
- package/harmony/blurhash/src/main/ets/{BlurhashPackage.ets → BlurhashPackage.ts} +2 -3
- package/harmony/blurhash/src/main/ets/BlurhashTurboModule.ts +2 -1
- package/{lib/commonjs/blurhash/ts.ets → harmony/blurhash/ts.ts} +1 -1
- package/harmony/blurhash.har +0 -0
- package/lib/commonjs/index.js +95 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/specs/NativeBlurhashModule.js +9 -0
- package/lib/commonjs/specs/NativeBlurhashModule.js.map +1 -0
- package/lib/commonjs/specs/NativeBlurhashView.js +10 -0
- package/lib/commonjs/specs/NativeBlurhashView.js.map +1 -0
- package/lib/commonjs/utils.js +56 -0
- package/lib/commonjs/utils.js.map +1 -0
- package/lib/module/index.js +85 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/specs/NativeBlurhashModule.js +3 -0
- package/lib/module/specs/NativeBlurhashModule.js.map +1 -0
- package/lib/module/specs/NativeBlurhashView.js +3 -0
- package/lib/module/specs/NativeBlurhashView.js.map +1 -0
- package/lib/module/utils.js +48 -0
- package/lib/module/utils.js.map +1 -0
- package/lib/typescript/index.d.ts +90 -0
- package/lib/typescript/specs/NativeBlurhashModule.d.ts +9 -0
- package/lib/typescript/specs/NativeBlurhashView.d.ts +19 -0
- package/lib/typescript/utils.d.ts +22 -0
- package/package.json +5 -12
- package/harmony/blurhash/ts.ets +0 -26
- package/lib/commonjs/blurhash/hvigorfile.js +0 -13
- package/lib/commonjs/blurhash/hvigorfile.js.map +0 -1
- package/lib/commonjs/blurhash/oh-package.json5 +0 -13
- package/lib/commonjs/blurhash/src/main/ets/BlurhashTurboModule.js +0 -49
- package/lib/commonjs/blurhash/src/main/ets/BlurhashTurboModule.js.map +0 -1
- package/lib/commonjs/blurhash/src/main/ets/Logger.js +0 -66
- package/lib/commonjs/blurhash/src/main/ets/Logger.js.map +0 -1
- package/lib/commonjs/blurhash/src/main/ets/RNCBlurhashView.js +0 -111
- package/lib/commonjs/blurhash/src/main/ets/RNCBlurhashView.js.map +0 -1
- package/lib/commonjs/blurhash/src/main/ets/RNCSpecs.js +0 -117
- package/lib/commonjs/blurhash/src/main/ets/RNCSpecs.js.map +0 -1
- package/lib/commonjs/blurhash/src/main/ets/TMSpecs.js +0 -34
- package/lib/commonjs/blurhash/src/main/ets/TMSpecs.js.map +0 -1
- package/lib/commonjs/blurhash.har +0 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Use these variables when you tailor your ArkTS code. They must be of the const type.
|
|
3
|
+
*/
|
|
4
|
+
export const HAR_VERSION = '2.1.0';
|
|
5
|
+
export const BUILD_MODE_NAME = 'debug';
|
|
6
|
+
export const DEBUG = true;
|
|
7
|
+
export const TARGET_NAME = 'default';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* BuildProfile Class is used only for compatibility purposes.
|
|
11
|
+
*/
|
|
12
|
+
export default class BuildProfile {
|
|
13
|
+
static readonly HAR_VERSION = HAR_VERSION;
|
|
14
|
+
static readonly BUILD_MODE_NAME = BUILD_MODE_NAME;
|
|
15
|
+
static readonly DEBUG = DEBUG;
|
|
16
|
+
static readonly TARGET_NAME = TARGET_NAME;
|
|
17
|
+
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* found in the LICENSE file.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
#include "Blurhash.
|
|
7
|
+
#include "Blurhash.hpp"
|
|
8
8
|
|
|
9
9
|
#include <algorithm>
|
|
10
10
|
#include <array>
|
|
@@ -21,58 +21,16 @@
|
|
|
21
21
|
#include "stb_image_write.h"
|
|
22
22
|
#include "stb_image.h"
|
|
23
23
|
#include <glog/logging.h>
|
|
24
|
-
#define MIN_BLURHASH_SIZE 6
|
|
25
|
-
#define AC_VALUE_MULTIPLIER 166
|
|
26
|
-
#define MIN_COMPONENT 1
|
|
27
|
-
#define MAX_COMPONENT 9
|
|
28
|
-
#define COMPONENT_3 3
|
|
29
|
-
#define CHANNELS_PER_PIXEL 3
|
|
30
|
-
#define CONSTANT_SIZE 2
|
|
31
|
-
#define MAX_PIXEL_VALUE 255
|
|
32
|
-
#define MAX_AC_SIZE 4
|
|
33
|
-
#define MAX_ENCODED_VALUE 82
|
|
34
|
-
#define BASE 83
|
|
35
|
-
#define DEFAULT_CHANNELS 3
|
|
36
|
-
#define LEFT_PADDING_2 2
|
|
37
|
-
#define LEFT_PADDING_4 4
|
|
38
|
-
#define RED_SHIFT 16
|
|
39
|
-
#define GREEN_SHIFT 8
|
|
40
|
-
#define MAX_X 9
|
|
41
|
-
#define HEX_DIGITS_PER_CHAR 2
|
|
42
|
-
#define QUANT_STEP 19
|
|
43
|
-
#define RED_CHANNEL 0
|
|
44
|
-
#define GREEN_CHANNEL 1
|
|
45
|
-
#define BLUE_CHANNEL 2
|
|
46
|
-
#define AC_COMPONENT_SIZE 2
|
|
47
|
-
#define EXPECTEDSIZE 4
|
|
48
24
|
|
|
49
25
|
using namespace std::literals;
|
|
50
26
|
|
|
51
27
|
namespace {
|
|
52
28
|
SparseArray<std::vector<double>> cacheCosinesX;
|
|
53
29
|
SparseArray<std::vector<double>> cacheCosinesY;
|
|
54
|
-
constexpr std::array<char, 84> int_to_b83{
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
inline bool NearEqual(const float left, const float right, const float epsilon)
|
|
58
|
-
{
|
|
59
|
-
return (std::abs(left - right) <= epsilon);
|
|
60
|
-
}
|
|
61
|
-
inline bool NearZero(const float value, const float epsilon)
|
|
62
|
-
{
|
|
63
|
-
return NearEqual(value, 0.0, epsilon);
|
|
64
|
-
}
|
|
65
|
-
inline bool NearZero(const float value)
|
|
66
|
-
{
|
|
67
|
-
constexpr float epsilon = 0.001f;
|
|
68
|
-
return NearZero(value, epsilon);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
std::string leftPad(std::string str, size_t len)
|
|
72
|
-
{
|
|
73
|
-
if (str.size() >= len) {
|
|
30
|
+
constexpr std::array<char, 84> int_to_b83{"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz#$%*+,-.:;=?@[]^_{|}~"};
|
|
31
|
+
std::string leftPad(std::string str, size_t len) {
|
|
32
|
+
if (str.size() >= len)
|
|
74
33
|
return str;
|
|
75
|
-
}
|
|
76
34
|
return str.insert(0, len - str.size(), '0');
|
|
77
35
|
}
|
|
78
36
|
constexpr std::array<int, 255> b83_to_int = []() constexpr {
|
|
@@ -84,178 +42,129 @@ constexpr std::array<int, 255> b83_to_int = []() constexpr {
|
|
|
84
42
|
}
|
|
85
43
|
return a;
|
|
86
44
|
}();
|
|
87
|
-
std::string encode83(int value)
|
|
88
|
-
{
|
|
45
|
+
std::string encode83(int value) {
|
|
89
46
|
std::string buffer;
|
|
90
47
|
do {
|
|
91
|
-
buffer += int_to_b83[value %
|
|
92
|
-
} while ((value = value /
|
|
48
|
+
buffer += int_to_b83[value % 83];
|
|
49
|
+
} while ((value = value / 83));
|
|
93
50
|
std::reverse(buffer.begin(), buffer.end());
|
|
94
51
|
return buffer;
|
|
95
52
|
}
|
|
96
53
|
struct Components {
|
|
97
54
|
int x, y;
|
|
98
55
|
};
|
|
99
|
-
int packComponents(const Components &c) noexcept
|
|
100
|
-
{
|
|
101
|
-
|
|
102
|
-
}
|
|
103
|
-
Components unpackComponents(int c) noexcept
|
|
104
|
-
{
|
|
105
|
-
return {c % MAX_X + 1, c / MAX_X + 1};
|
|
106
|
-
}
|
|
107
|
-
int decode83(std::string_view value)
|
|
108
|
-
{
|
|
56
|
+
int packComponents(const Components &c) noexcept { return (c.x - 1) + (c.y - 1) * 9; }
|
|
57
|
+
Components unpackComponents(int c) noexcept { return {c % 9 + 1, c / 9 + 1}; }
|
|
58
|
+
int decode83(std::string_view value) {
|
|
109
59
|
int temp = 0;
|
|
110
60
|
for (char c : value)
|
|
111
61
|
if (b83_to_int[static_cast<unsigned char>(c)] < 0)
|
|
112
62
|
throw std::invalid_argument("invalid character in blurhash");
|
|
113
63
|
for (char c : value)
|
|
114
|
-
temp = temp *
|
|
64
|
+
temp = temp * 83 + b83_to_int[static_cast<unsigned char>(c)];
|
|
115
65
|
return temp;
|
|
116
66
|
}
|
|
117
|
-
float decodeMaxAC(int quantizedMaxAC) noexcept
|
|
118
|
-
{
|
|
119
|
-
|
|
120
|
-
}
|
|
121
|
-
float decodeMaxAC(std::string_view maxAC)
|
|
122
|
-
{
|
|
123
|
-
if (maxAC.size() != 1) {
|
|
124
|
-
return 0.0f;
|
|
125
|
-
}
|
|
67
|
+
float decodeMaxAC(int quantizedMaxAC) noexcept { return static_cast<float>(quantizedMaxAC + 1) / 166.f; }
|
|
68
|
+
float decodeMaxAC(std::string_view maxAC) {
|
|
69
|
+
assert(maxAC.size() == 1);
|
|
126
70
|
return decodeMaxAC(decode83(maxAC));
|
|
127
71
|
}
|
|
128
|
-
int encodeMaxAC(float maxAC) noexcept
|
|
129
|
-
{
|
|
130
|
-
return std::max(0, std::min(MAX_ENCODED_VALUE, int(maxAC * AC_VALUE_MULTIPLIER - 0.5f)));
|
|
131
|
-
}
|
|
132
|
-
float srgbToLinear(int value) noexcept
|
|
133
|
-
{
|
|
72
|
+
int encodeMaxAC(float maxAC) noexcept { return std::max(0, std::min(82, int(maxAC * 166 - 0.5f))); }
|
|
73
|
+
float srgbToLinear(int value) noexcept {
|
|
134
74
|
auto srgbToLinearF = [](float x) {
|
|
135
|
-
if (x <= 0.0f)
|
|
75
|
+
if (x <= 0.0f)
|
|
136
76
|
return 0.0f;
|
|
137
|
-
|
|
77
|
+
else if (x >= 1.0f)
|
|
138
78
|
return 1.0f;
|
|
139
|
-
|
|
79
|
+
else if (x < 0.04045f)
|
|
140
80
|
return x / 12.92f;
|
|
141
|
-
|
|
81
|
+
else
|
|
142
82
|
return std::pow((x + 0.055f) / 1.055f, 2.4f);
|
|
143
|
-
}
|
|
144
83
|
};
|
|
145
84
|
return srgbToLinearF(static_cast<float>(value) / 255.f);
|
|
146
85
|
}
|
|
147
|
-
int linearToSrgb(float value) noexcept
|
|
148
|
-
{
|
|
86
|
+
int linearToSrgb(float value) noexcept {
|
|
149
87
|
auto linearToSrgbF = [](float x) -> float {
|
|
150
|
-
if (x <= 0.0f)
|
|
88
|
+
if (x <= 0.0f)
|
|
151
89
|
return 0.0f;
|
|
152
|
-
|
|
90
|
+
else if (x >= 1.0f)
|
|
153
91
|
return 1.0f;
|
|
154
|
-
|
|
92
|
+
else if (x < 0.0031308f)
|
|
155
93
|
return x * 12.92f;
|
|
156
|
-
|
|
94
|
+
else
|
|
157
95
|
return std::pow(x, 1.0f / 2.4f) * 1.055f - 0.055f;
|
|
158
|
-
}
|
|
159
96
|
};
|
|
160
97
|
return int(linearToSrgbF(value) * 255.f + 0.5f);
|
|
161
98
|
}
|
|
162
99
|
struct Color {
|
|
163
100
|
float r, g, b;
|
|
164
|
-
Color &operator*=(float scale)
|
|
165
|
-
{
|
|
101
|
+
Color &operator*=(float scale) {
|
|
166
102
|
r *= scale;
|
|
167
103
|
g *= scale;
|
|
168
104
|
b *= scale;
|
|
169
105
|
return *this;
|
|
170
106
|
}
|
|
171
|
-
friend Color operator*(Color lhs, float rhs)
|
|
172
|
-
{
|
|
173
|
-
return (lhs *= rhs);
|
|
174
|
-
}
|
|
175
|
-
Color &operator/=(float scale)
|
|
176
|
-
{
|
|
177
|
-
if (NearZero(scale)) {
|
|
178
|
-
return *this;
|
|
179
|
-
}
|
|
107
|
+
friend Color operator*(Color lhs, float rhs) { return (lhs *= rhs); }
|
|
108
|
+
Color &operator/=(float scale) {
|
|
180
109
|
r /= scale;
|
|
181
110
|
g /= scale;
|
|
182
111
|
b /= scale;
|
|
183
112
|
return *this;
|
|
184
113
|
}
|
|
185
|
-
Color &operator+=(const Color &rhs)
|
|
186
|
-
{
|
|
114
|
+
Color &operator+=(const Color &rhs) {
|
|
187
115
|
r += rhs.r;
|
|
188
116
|
g += rhs.g;
|
|
189
117
|
b += rhs.b;
|
|
190
118
|
return *this;
|
|
191
119
|
}
|
|
192
120
|
};
|
|
193
|
-
Color decodeDC(int value)
|
|
194
|
-
{
|
|
121
|
+
Color decodeDC(int value) {
|
|
195
122
|
const int intR = value >> 16;
|
|
196
123
|
const int intG = (value >> 8) & 255;
|
|
197
124
|
const int intB = value & 255;
|
|
198
125
|
return {srgbToLinear(intR), srgbToLinear(intG), srgbToLinear(intB)};
|
|
199
126
|
}
|
|
200
|
-
Color decodeDC(std::string_view value)
|
|
201
|
-
|
|
202
|
-
if (value.size() != EXPECTEDSIZE) {
|
|
203
|
-
return Color{0.0f, 0.0f, 0.0f};
|
|
204
|
-
}
|
|
127
|
+
Color decodeDC(std::string_view value) {
|
|
128
|
+
assert(value.size() == 4);
|
|
205
129
|
return decodeDC(decode83(value));
|
|
206
130
|
}
|
|
207
|
-
int encodeDC(const Color &c)
|
|
208
|
-
{
|
|
209
|
-
|
|
210
|
-
}
|
|
211
|
-
float signPow(float value, float exp)
|
|
212
|
-
{
|
|
213
|
-
return std::copysign(std::pow(std::abs(value), exp), value);
|
|
214
|
-
}
|
|
215
|
-
int encodeAC(const Color &c, float maximumValue)
|
|
216
|
-
{
|
|
217
|
-
if (maximumValue == 0) {
|
|
218
|
-
return -1;
|
|
219
|
-
}
|
|
131
|
+
int encodeDC(const Color &c) { return (linearToSrgb(c.r) << 16) + (linearToSrgb(c.g) << 8) + linearToSrgb(c.b); }
|
|
132
|
+
float signPow(float value, float exp) { return std::copysign(std::pow(std::abs(value), exp), value); }
|
|
133
|
+
int encodeAC(const Color &c, float maximumValue) {
|
|
220
134
|
auto quantR = int(std::max(0., std::min(18., std::floor(signPow(c.r / maximumValue, 0.5) * 9 + 9.5))));
|
|
221
135
|
auto quantG = int(std::max(0., std::min(18., std::floor(signPow(c.g / maximumValue, 0.5) * 9 + 9.5))));
|
|
222
136
|
auto quantB = int(std::max(0., std::min(18., std::floor(signPow(c.b / maximumValue, 0.5) * 9 + 9.5))));
|
|
223
|
-
return quantR *
|
|
137
|
+
return quantR * 19 * 19 + quantG * 19 + quantB;
|
|
224
138
|
}
|
|
225
|
-
Color decodeAC(int value, float maximumValue)
|
|
226
|
-
|
|
227
|
-
auto
|
|
228
|
-
auto
|
|
229
|
-
|
|
230
|
-
return {signPow((float(quantR) - 9) / 9, 2) * maximumValue,
|
|
231
|
-
signPow((float(quantG) - 9) / 9, 2) * maximumValue, signPow((float(quantB) - 9) / 9, 2) * maximumValue};
|
|
232
|
-
}
|
|
233
|
-
Color decodeAC(std::string_view value, float maximumValue)
|
|
234
|
-
{
|
|
235
|
-
return decodeAC(decode83(value), maximumValue);
|
|
139
|
+
Color decodeAC(int value, float maximumValue) {
|
|
140
|
+
auto quantR = value / (19 * 19);
|
|
141
|
+
auto quantG = (value / 19) % 19;
|
|
142
|
+
auto quantB = value % 19;
|
|
143
|
+
|
|
144
|
+
return {signPow((float(quantR) - 9) / 9, 2) * maximumValue, signPow((float(quantG) - 9) / 9, 2) * maximumValue, signPow((float(quantB) - 9) / 9, 2) * maximumValue};
|
|
236
145
|
}
|
|
146
|
+
Color decodeAC(std::string_view value, float maximumValue) { return decodeAC(decode83(value), maximumValue); }
|
|
237
147
|
const float pi = std::acos(-1.0f);
|
|
238
|
-
std::vector<float> bases_for(size_t dimension, size_t components)
|
|
239
|
-
{
|
|
148
|
+
std::vector<float> bases_for(size_t dimension, size_t components) {
|
|
240
149
|
std::vector<float> bases(dimension * components);
|
|
150
|
+
|
|
241
151
|
float scale = pi / float(dimension);
|
|
152
|
+
|
|
242
153
|
size_t index = 0;
|
|
243
154
|
std::generate(bases.begin(), bases.end(), [&]() {
|
|
244
|
-
if (components == 0) {
|
|
245
|
-
throw std::invalid_argument("components cannot be zero");
|
|
246
|
-
}
|
|
247
155
|
size_t x = index / components;
|
|
248
156
|
size_t nx = index % components;
|
|
249
157
|
index++;
|
|
250
158
|
return std::cos(scale * float(nx * x));
|
|
251
159
|
});
|
|
160
|
+
|
|
252
161
|
return bases;
|
|
253
162
|
}
|
|
254
163
|
|
|
255
164
|
|
|
256
165
|
} // namespace
|
|
257
166
|
namespace blurhash {
|
|
258
|
-
std::string path = "/data/storage/el2/base/haps/entry/cache/";
|
|
167
|
+
std::string path = "/data/storage/el2/base/haps/entry/cache/rn_image_cache/";
|
|
259
168
|
/**
|
|
260
169
|
* @brief 解码Blurhash为图像
|
|
261
170
|
* @param blurhash 待解码的Blurhash字符串
|
|
@@ -269,30 +178,28 @@ std::string path = "/data/storage/el2/base/haps/entry/cache/";
|
|
|
269
178
|
* 如果解码失败,则返回空图像。接着解码最大AC值和平均颜色值。然后解码AC值并将其添加到值向量中。
|
|
270
179
|
* 最后使用解码的值和基础函数计算图像的每个像素的颜色,并将其存储在图像的image数组中。
|
|
271
180
|
*/
|
|
272
|
-
std::string decode(std::string_view blurhash, size_t width, size_t height, float punch, bool useCache) noexcept
|
|
273
|
-
{
|
|
181
|
+
std::string decode(std::string_view blurhash, size_t width, size_t height, float punch, bool useCache) noexcept {
|
|
274
182
|
size_t bytesPerPixel = 3;
|
|
275
183
|
Image i{};
|
|
276
|
-
if (blurhash.size() <
|
|
184
|
+
if (blurhash.size() < 6)
|
|
277
185
|
return "";
|
|
278
186
|
Components components{};
|
|
279
187
|
std::vector<Color> values;
|
|
280
|
-
values.reserve(blurhash.size() /
|
|
188
|
+
values.reserve(blurhash.size() / 2);
|
|
281
189
|
try {
|
|
282
190
|
components = unpackComponents(decode83(blurhash.substr(0, 1)));
|
|
283
|
-
if (components.x < 1 || components.y < 1 ||
|
|
284
|
-
blurhash.size() != size_t(1 + 1 + MAX_AC_SIZE + (components.x * components.y - 1) * AC_COMPONENT_SIZE))
|
|
191
|
+
if (components.x < 1 || components.y < 1 || blurhash.size() != size_t(1 + 1 + 4 + (components.x * components.y - 1) * 2))
|
|
285
192
|
return {};
|
|
286
193
|
auto maxAC = decodeMaxAC(blurhash.substr(1, 1));
|
|
287
194
|
maxAC *= punch;
|
|
288
195
|
Color average = decodeDC(blurhash.substr(2, 4));
|
|
289
196
|
values.push_back(average);
|
|
290
|
-
for (size_t c = 6; c < blurhash.size(); c +=
|
|
291
|
-
values.push_back(decodeAC(blurhash.substr(c,
|
|
197
|
+
for (size_t c = 6; c < blurhash.size(); c += 2)
|
|
198
|
+
values.push_back(decodeAC(blurhash.substr(c, 2), maxAC));
|
|
292
199
|
} catch (std::invalid_argument &) {
|
|
293
200
|
return {};
|
|
294
201
|
}
|
|
295
|
-
i.image = decltype(i.image)(height * width * bytesPerPixel,
|
|
202
|
+
i.image = decltype(i.image)(height * width * bytesPerPixel, 255);
|
|
296
203
|
std::vector<float> basis_x = bases_for(width, components.x);
|
|
297
204
|
std::vector<float> basis_y = bases_for(height, components.y);
|
|
298
205
|
for (size_t y = 0; y < height; y++) {
|
|
@@ -304,18 +211,20 @@ std::string decode(std::string_view blurhash, size_t width, size_t height, float
|
|
|
304
211
|
c += values[nx + ny * components.x] * basis;
|
|
305
212
|
}
|
|
306
213
|
}
|
|
307
|
-
i.image[(y * width + x) * bytesPerPixel +
|
|
308
|
-
i.image[(y * width + x) * bytesPerPixel +
|
|
309
|
-
i.image[(y * width + x) * bytesPerPixel +
|
|
214
|
+
i.image[(y * width + x) * bytesPerPixel + 0] = static_cast<unsigned char>(linearToSrgb(c.r));
|
|
215
|
+
i.image[(y * width + x) * bytesPerPixel + 1] = static_cast<unsigned char>(linearToSrgb(c.g));
|
|
216
|
+
i.image[(y * width + x) * bytesPerPixel + 2] = static_cast<unsigned char>(linearToSrgb(c.b));
|
|
310
217
|
}
|
|
311
218
|
}
|
|
312
219
|
i.height = height;
|
|
313
220
|
i.width = width;
|
|
314
221
|
|
|
315
222
|
std::string filename = path + std::string(blurhash) + ".bmp";
|
|
316
|
-
stbi_write_bmp(filename.c_str(), i.width, i.height,
|
|
223
|
+
stbi_write_bmp(filename.c_str(), i.width, i.height, 3, (void *)i.image.data());
|
|
317
224
|
return filename;
|
|
318
225
|
}
|
|
226
|
+
|
|
227
|
+
|
|
319
228
|
/**
|
|
320
229
|
* 对图像进行编码的函数
|
|
321
230
|
* @param image 待编码的图像数据
|
|
@@ -325,19 +234,15 @@ std::string decode(std::string_view blurhash, size_t width, size_t height, float
|
|
|
325
234
|
* @param components_y 在y方向上的分量数
|
|
326
235
|
* @return 编码后的字符串
|
|
327
236
|
*/
|
|
328
|
-
std::string encode(char const *
|
|
329
|
-
{
|
|
237
|
+
std::string encode(char const *filename, int components_x, int components_y) {
|
|
330
238
|
auto start = std::chrono::steady_clock::now();
|
|
331
239
|
auto duration = std::chrono::seconds(5);
|
|
332
|
-
int width;
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
unsigned char *data = stbi_load(filepath, &width, &height, &n, DEFAULT_CHANNELS);
|
|
336
|
-
if (components_x < MIN_COMPONENT || components_x > MAX_COMPONENT ||
|
|
337
|
-
components_y < MIN_COMPONENT || components_y > MAX_COMPONENT)
|
|
240
|
+
int width, height, n;
|
|
241
|
+
unsigned char *data = stbi_load((path + filename).c_str(), &width, &height, &n, 3);
|
|
242
|
+
if (components_x < 1 || components_x > 9 || components_y < 1 || components_y > 9)
|
|
338
243
|
return "";
|
|
339
244
|
while (width < 1 || height < 1 || !data) {
|
|
340
|
-
data = stbi_load(
|
|
245
|
+
data = stbi_load((path + filename).c_str(), &width, &height, &n, 3);
|
|
341
246
|
auto now = std::chrono::steady_clock::now();
|
|
342
247
|
if (now - start >= duration) {
|
|
343
248
|
return "";
|
|
@@ -348,8 +253,7 @@ std::string encode(char const *filepath, int components_x, int components_y)
|
|
|
348
253
|
std::vector<Color> factors(components_x * components_y, Color{});
|
|
349
254
|
for (size_t y = 0; y < height; y++) {
|
|
350
255
|
for (size_t x = 0; x < width; x++) {
|
|
351
|
-
Color linear{srgbToLinear(data[3 * x + 0 + y * width * 3]),
|
|
352
|
-
srgbToLinear(data[3 * x + 1 + y * width * 3]), srgbToLinear(data[3 * x + 2 + y * width * 3])};
|
|
256
|
+
Color linear{srgbToLinear(data[3 * x + 0 + y * width * 3]), srgbToLinear(data[3 * x + 1 + y * width * 3]), srgbToLinear(data[3 * x + 2 + y * width * 3])};
|
|
353
257
|
linear *= 1.f / static_cast<float>(width);
|
|
354
258
|
for (size_t ny = 0; ny < size_t(components_y); ny++) {
|
|
355
259
|
for (size_t nx = 0; nx < size_t(components_x); nx++) {
|
|
@@ -364,9 +268,7 @@ std::string encode(char const *filepath, int components_x, int components_y)
|
|
|
364
268
|
float scale = normalisation / static_cast<float>(height);
|
|
365
269
|
factors[i] *= scale;
|
|
366
270
|
}
|
|
367
|
-
|
|
368
|
-
throw std::runtime_error("Factors array is empty");
|
|
369
|
-
}
|
|
271
|
+
assert(factors.size() > 0);
|
|
370
272
|
auto dc = factors.front();
|
|
371
273
|
factors.erase(factors.begin());
|
|
372
274
|
std::string h;
|
|
@@ -383,26 +285,30 @@ std::string encode(char const *filepath, int components_x, int components_y)
|
|
|
383
285
|
});
|
|
384
286
|
}
|
|
385
287
|
int quantisedMaximumValue = encodeMaxAC(actualMaximumValue);
|
|
386
|
-
maximumValue = ((float)quantisedMaximumValue + 1) /
|
|
288
|
+
maximumValue = ((float)quantisedMaximumValue + 1) / 166;
|
|
387
289
|
h += leftPad(encode83(quantisedMaximumValue), 1);
|
|
388
290
|
} else {
|
|
389
291
|
maximumValue = 1;
|
|
390
292
|
h += leftPad(encode83(0), 1);
|
|
391
293
|
}
|
|
392
|
-
h += leftPad(encode83(encodeDC(dc)),
|
|
294
|
+
h += leftPad(encode83(encodeDC(dc)), 4);
|
|
393
295
|
for (auto ac : factors)
|
|
394
|
-
h += leftPad(encode83(encodeAC(ac, maximumValue)),
|
|
296
|
+
h += leftPad(encode83(encodeAC(ac, maximumValue)), 2);
|
|
297
|
+
|
|
395
298
|
return h;
|
|
396
299
|
}
|
|
397
|
-
|
|
398
|
-
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
void clearCache() {
|
|
303
|
+
|
|
399
304
|
DLOG(INFO) << "clearCosineCache:SparseArray<std::vector<double>> Object";
|
|
400
305
|
DLOG(INFO) << "clearCosineCache:SparseArray<std::vector<double>> Object";
|
|
401
306
|
cacheCosinesX.clear();
|
|
402
|
-
cacheCosinesY.clear();
|
|
307
|
+
cacheCosinesY.clear();
|
|
403
308
|
DLOG(INFO) << "clearCosineCache:null";
|
|
404
309
|
DLOG(INFO) << "clearCosineCache:null";
|
|
405
310
|
}
|
|
406
311
|
} // namespace blurhash
|
|
312
|
+
|
|
407
313
|
#ifdef DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
|
|
408
314
|
#endif
|
|
@@ -3,8 +3,7 @@
|
|
|
3
3
|
* Use of this source code is governed by a MIT license that can be
|
|
4
4
|
* found in the LICENSE file.
|
|
5
5
|
*/
|
|
6
|
-
|
|
7
|
-
#define BLURHASH_H
|
|
6
|
+
|
|
8
7
|
#pragma once
|
|
9
8
|
|
|
10
9
|
#include <__functional/function.h>
|
|
@@ -19,12 +18,10 @@ struct Image {
|
|
|
19
18
|
std::vector<unsigned char> image; // pixels rgb
|
|
20
19
|
};
|
|
21
20
|
|
|
22
|
-
std::string decode(std::string_view blurhash, size_t width = 32,
|
|
23
|
-
size_t height = 32, float punch = 1.0, bool useCache = true) noexcept;
|
|
21
|
+
std::string decode(std::string_view blurhash, size_t width = 32, size_t height = 32, float punch = 1.0, bool useCache = true) noexcept;
|
|
24
22
|
|
|
25
|
-
std::string encode(char const *
|
|
23
|
+
std::string encode(char const *filename, int components_x, int components_y);
|
|
26
24
|
|
|
27
25
|
void clearCache();
|
|
28
26
|
|
|
29
27
|
} // namespace blurhash
|
|
30
|
-
#endif
|
|
@@ -9,32 +9,29 @@
|
|
|
9
9
|
#include <string_view>
|
|
10
10
|
#include "RNOH/arkui/NativeNodeApi.h"
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
|
|
13
|
+
static constexpr ArkUI_NodeEventType IMAGE_NODE_EVENT_TYPES[] = {NODE_IMAGE_ON_COMPLETE, NODE_IMAGE_ON_ERROR, NODE_IMAGE_ON_DOWNLOAD_PROGRESS};
|
|
14
14
|
|
|
15
15
|
namespace rnoh {
|
|
16
|
+
|
|
16
17
|
using namespace std::literals;
|
|
17
18
|
constexpr std::string_view ASSET_PREFIX = "asset://"sv;
|
|
18
19
|
const std::string RAWFILE_PREFIX = "resource://RAWFILE/assets/";
|
|
19
20
|
|
|
20
21
|
BlurhashNode::BlurhashNode()
|
|
21
|
-
: ArkUINode(NativeNodeApi::getInstance()->createNode(ArkUI_NodeType::ARKUI_NODE_IMAGE)),
|
|
22
|
-
m_childArkUINodeHandle(nullptr), m_blurhashNodeDelegate(nullptr)
|
|
23
|
-
{
|
|
22
|
+
: ArkUINode(NativeNodeApi::getInstance()->createNode(ArkUI_NodeType::ARKUI_NODE_IMAGE)), m_childArkUINodeHandle(nullptr), m_blurhashNodeDelegate(nullptr) {
|
|
24
23
|
for (auto eventType : IMAGE_NODE_EVENT_TYPES) {
|
|
25
24
|
maybeThrow(NativeNodeApi::getInstance()->registerNodeEvent(m_nodeHandle, eventType, eventType, this));
|
|
26
25
|
}
|
|
27
26
|
}
|
|
28
27
|
|
|
29
|
-
BlurhashNode::~BlurhashNode()
|
|
30
|
-
{
|
|
28
|
+
BlurhashNode::~BlurhashNode() {
|
|
31
29
|
for (auto eventType : IMAGE_NODE_EVENT_TYPES) {
|
|
32
30
|
NativeNodeApi::getInstance()->unregisterNodeEvent(m_nodeHandle, eventType);
|
|
33
31
|
}
|
|
34
32
|
}
|
|
35
33
|
|
|
36
|
-
BlurhashNode &BlurhashNode::setSource(std::string const &uri, std::string prefix)
|
|
37
|
-
{
|
|
34
|
+
BlurhashNode &BlurhashNode::setSource(std::string const &uri, std::string prefix) {
|
|
38
35
|
ArkUI_AttributeItem item;
|
|
39
36
|
std::string absolutePath = prefix == "" ? RAWFILE_PREFIX : prefix;
|
|
40
37
|
if (uri.rfind(ASSET_PREFIX, 0) == 0) {
|
|
@@ -47,13 +44,9 @@ BlurhashNode &BlurhashNode::setSource(std::string const &uri, std::string prefix
|
|
|
47
44
|
return *this;
|
|
48
45
|
}
|
|
49
46
|
|
|
50
|
-
void BlurhashNode::setNodeDelegate(BlurhashNodeDelegate *blurhashNodeDelegate)
|
|
51
|
-
{
|
|
52
|
-
m_blurhashNodeDelegate = blurhashNodeDelegate;
|
|
53
|
-
}
|
|
47
|
+
void BlurhashNode::setNodeDelegate(BlurhashNodeDelegate *blurhashNodeDelegate) { m_blurhashNodeDelegate = blurhashNodeDelegate; }
|
|
54
48
|
|
|
55
|
-
void BlurhashNode::onNodeEvent(ArkUI_NodeEventType eventType, EventArgs &eventArgs)
|
|
56
|
-
{
|
|
49
|
+
void BlurhashNode::onNodeEvent(ArkUI_NodeEventType eventType, EventArgs &eventArgs){
|
|
57
50
|
if (eventType == ArkUI_NodeEventType::NODE_IMAGE_ON_COMPLETE) {
|
|
58
51
|
if (m_blurhashNodeDelegate != nullptr && eventArgs[0].i32 == 1) {
|
|
59
52
|
m_blurhashNodeDelegate->onComplete();
|
|
@@ -73,8 +66,7 @@ void BlurhashNode::onNodeEvent(ArkUI_NodeEventType eventType, EventArgs &eventAr
|
|
|
73
66
|
}
|
|
74
67
|
}
|
|
75
68
|
|
|
76
|
-
BlurhashNode &BlurhashNode::setResizeMode(facebook::react::ImageResizeMode const &mode)
|
|
77
|
-
{
|
|
69
|
+
BlurhashNode &BlurhashNode::setResizeMode(facebook::react::ImageResizeMode const &mode) {
|
|
78
70
|
int32_t val = ARKUI_OBJECT_FIT_COVER;
|
|
79
71
|
if (mode == facebook::react::ImageResizeMode::Cover) {
|
|
80
72
|
val = ARKUI_OBJECT_FIT_COVER;
|
|
@@ -85,9 +77,11 @@ BlurhashNode &BlurhashNode::setResizeMode(facebook::react::ImageResizeMode const
|
|
|
85
77
|
} else if (mode == facebook::react::ImageResizeMode::Center || mode == facebook::react::ImageResizeMode::Repeat) {
|
|
86
78
|
val = ARKUI_OBJECT_FIT_NONE;
|
|
87
79
|
}
|
|
80
|
+
|
|
88
81
|
ArkUI_NumberValue value[] = {{.i32 = val}};
|
|
89
82
|
ArkUI_AttributeItem item = {value, sizeof(value) / sizeof(ArkUI_NumberValue)};
|
|
90
83
|
maybeThrow(NativeNodeApi::getInstance()->setAttribute(m_nodeHandle, NODE_IMAGE_OBJECT_FIT, &item));
|
|
91
84
|
return *this;
|
|
92
85
|
}
|
|
93
|
-
|
|
86
|
+
|
|
87
|
+
} // namespace rnoh
|
|
@@ -3,14 +3,14 @@
|
|
|
3
3
|
* Use of this source code is governed by a MIT license that can be
|
|
4
4
|
* found in the LICENSE file.
|
|
5
5
|
*/
|
|
6
|
-
|
|
7
|
-
#define BLURHASHNODE_H
|
|
6
|
+
|
|
8
7
|
#pragma once
|
|
9
8
|
#include <cstdint>
|
|
10
9
|
#include <react/renderer/imagemanager/primitives.h>
|
|
11
10
|
#include "RNOH/arkui/ArkUINode.h"
|
|
12
11
|
|
|
13
12
|
namespace rnoh {
|
|
13
|
+
|
|
14
14
|
class BlurhashNodeDelegate {
|
|
15
15
|
public:
|
|
16
16
|
virtual ~BlurhashNodeDelegate() = default;
|
|
@@ -33,4 +33,3 @@ public:
|
|
|
33
33
|
void setNodeDelegate(BlurhashNodeDelegate *blurhashNodeDelegate);
|
|
34
34
|
};
|
|
35
35
|
} // namespace rnoh
|
|
36
|
-
#endif
|
|
@@ -3,20 +3,20 @@
|
|
|
3
3
|
* Use of this source code is governed by a MIT license that can be
|
|
4
4
|
* found in the LICENSE file.
|
|
5
5
|
*/
|
|
6
|
-
|
|
7
|
-
#define BLURHASHPACKAGE_H
|
|
6
|
+
|
|
8
7
|
#include "RNOH/Package.h"
|
|
9
8
|
#include "ComponentDescriptors.h"
|
|
10
9
|
#include "BlurhashViewJSIBinder.h"
|
|
11
10
|
#include "RNBlurhashTurboModule.h"
|
|
12
11
|
#include "BlurhashViewComponentInstance.h"
|
|
13
|
-
|
|
12
|
+
|
|
13
|
+
using namespace rnoh;
|
|
14
14
|
|
|
15
15
|
class BlurhashViewComponentInstanceFactoryDelegate : public ComponentInstanceFactoryDelegate {
|
|
16
16
|
public:
|
|
17
17
|
using ComponentInstanceFactoryDelegate::ComponentInstanceFactoryDelegate;
|
|
18
|
-
|
|
19
|
-
{
|
|
18
|
+
|
|
19
|
+
ComponentInstance::Shared create(ComponentInstance::Context ctx) override {
|
|
20
20
|
if (ctx.componentName == "BlurhashView") {
|
|
21
21
|
return std::make_shared<BlurhashViewComponentInstance>(std::move(ctx));
|
|
22
22
|
}
|
|
@@ -26,8 +26,7 @@ public:
|
|
|
26
26
|
|
|
27
27
|
class BlurhashTurboModuleFactoryDelegate : public TurboModuleFactoryDelegate {
|
|
28
28
|
public:
|
|
29
|
-
SharedTurboModule createTurboModule(Context ctx, const std::string &name) const override
|
|
30
|
-
{
|
|
29
|
+
SharedTurboModule createTurboModule(Context ctx, const std::string &name) const override {
|
|
31
30
|
if (name == "BlurhashModule") {
|
|
32
31
|
return std::make_shared<RNBlurhashTurboModule>(ctx, name);
|
|
33
32
|
}
|
|
@@ -39,26 +38,16 @@ class BlurhashPackage : public Package {
|
|
|
39
38
|
public:
|
|
40
39
|
BlurhashPackage(Package::Context ctx) : Package(ctx) {}
|
|
41
40
|
|
|
42
|
-
std::unique_ptr<TurboModuleFactoryDelegate> createTurboModuleFactoryDelegate() override
|
|
43
|
-
{
|
|
44
|
-
return std::make_unique<BlurhashTurboModuleFactoryDelegate>();
|
|
45
|
-
}
|
|
41
|
+
std::unique_ptr<TurboModuleFactoryDelegate> createTurboModuleFactoryDelegate() override { return std::make_unique<BlurhashTurboModuleFactoryDelegate>(); }
|
|
46
42
|
|
|
47
|
-
ComponentInstanceFactoryDelegate::Shared createComponentInstanceFactoryDelegate() override
|
|
48
|
-
{
|
|
43
|
+
ComponentInstanceFactoryDelegate::Shared createComponentInstanceFactoryDelegate() override {
|
|
49
44
|
return std::make_shared<BlurhashViewComponentInstanceFactoryDelegate>();
|
|
50
45
|
}
|
|
51
46
|
|
|
52
|
-
std::vector<facebook::react::ComponentDescriptorProvider> createComponentDescriptorProviders() override
|
|
53
|
-
|
|
54
|
-
return {facebook::react::concreteComponentDescriptorProvider<
|
|
55
|
-
facebook::react::BlurhashViewComponentDescriptor>()};
|
|
47
|
+
std::vector<facebook::react::ComponentDescriptorProvider> createComponentDescriptorProviders() override {
|
|
48
|
+
return {facebook::react::concreteComponentDescriptorProvider<facebook::react::BlurhashViewComponentDescriptor>()};
|
|
56
49
|
}
|
|
57
50
|
|
|
58
|
-
ComponentJSIBinderByString createComponentJSIBinderByName() override
|
|
59
|
-
{
|
|
60
|
-
return {{"BlurhashView", std::make_shared<BlurhashViewJSIBinder>()}};
|
|
61
|
-
}
|
|
51
|
+
ComponentJSIBinderByString createComponentJSIBinderByName() override { return {{"BlurhashView", std::make_shared<BlurhashViewJSIBinder>()}}; }
|
|
62
52
|
};
|
|
63
|
-
|
|
64
|
-
#endif
|
|
53
|
+
// namespace rnoh
|