Skip to content

Commit aff613a

Browse files
committed
fix mitchell scaling, improve lancszos
1 parent 3afc2f0 commit aff613a

File tree

2 files changed

+48
-39
lines changed

2 files changed

+48
-39
lines changed

JxlCoder.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Pod::Spec.new do |s|
22
s.name = 'JxlCoder'
3-
s.version = '1.1.10'
3+
s.version = '1.1.11'
44
s.summary = 'JXL coder for iOS and MacOS'
55
s.description = 'Provides support for JXL files in iOS and MacOS'
66
s.homepage = 'https://github.com/awxkee/jxl-coder-swift'

Sources/jxlc/XScaler.mm

Lines changed: 47 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,22 @@
2626
return result;
2727
}
2828

29+
template <typename T, typename D>
30+
inline D PromoteTo(T t, float maxColors) {
31+
D result = static_cast<D>((float)t / maxColors);
32+
return result;
33+
}
34+
2935
template <typename T>
3036
inline T DemoteHalfTo(half t, float maxColors) {
3137
return (T)clamp(((float)t * (float)maxColors), 0.0f, (float)maxColors);
3238
}
3339

40+
template <typename T, typename D>
41+
inline D DemoteTo(T t, float maxColors) {
42+
return (D)clamp(((float)t * (float)maxColors), 0.0f, (float)maxColors);
43+
}
44+
3445
template <typename T>
3546
inline T CubicBSpline(T t) {
3647
T absX = abs(t);
@@ -131,8 +142,8 @@ void scaleImageFloat16(uint16_t* input,
131142
int y1 = static_cast<int>(srcY);
132143

133144
if (option == bilinear) {
134-
int x2 = std::min(x1 + 1, inputWidth - 1);
135-
int y2 = std::min(y1 + 1, inputHeight - 1);
145+
int x2 = min(x1 + 1, inputWidth - 1);
146+
int y2 = min(y1 + 1, inputHeight - 1);
136147

137148
half dx(x2 - x1);
138149
half dy(y2 - y1);
@@ -150,9 +161,6 @@ void scaleImageFloat16(uint16_t* input,
150161
dst16[x*components + c] = result.data_;
151162
}
152163
} else if (option == cubic) {
153-
half dx = half(srcX - x);
154-
half dy = half(srcY - y);
155-
156164
half rgb[components];
157165

158166
for (int j = -1; j <= 2; j++) {
@@ -163,7 +171,7 @@ void scaleImageFloat16(uint16_t* input,
163171
half weight = CubicBSpline(half(srcX - xi)) * CubicBSpline(half(srcY - yj));
164172

165173
for (int c = 0; c < components; ++c) {
166-
half clrf = castU16(reinterpret_cast<const uint16_t*>(src8 + clamp(yj, 0, inputHeight - 1) * srcStride)[clamp(x, 0, inputWidth - 1)*components + c]);
174+
half clrf = castU16(reinterpret_cast<const uint16_t*>(src8 + clamp(yj, 0, inputHeight - 1) * srcStride)[clamp(xi, 0, inputWidth - 1)*components + c]);
167175
half clr = clrf * weight;
168176
rgb[c] += clr;
169177
}
@@ -174,9 +182,6 @@ void scaleImageFloat16(uint16_t* input,
174182
dst16[x*components + c] = rgb[c].data_;
175183
}
176184
} else if (option == mitchell) {
177-
half dx = half(srcX - x);
178-
half dy = half(srcY - y);
179-
180185
half rgb[components];
181186

182187
for (int j = -1; j <= 2; j++) {
@@ -214,37 +219,38 @@ void scaleImageFloat16(uint16_t* input,
214219
dst16[x*components + c] += clr.data_;
215220
}
216221
} else if (option == lanczos) {
217-
half rgb[components];
222+
float rgb[components];
223+
memset(&rgb[0], 0.0f, sizeof(float) * components);
218224

219225
int a = 3;
220226
float lanczosFA = float(3.0f);
221227

222228
float kx1 = floor(srcX);
223229
float ky1 = floor(srcY);
224230

225-
half weightSum(0.0f);
231+
float weightSum(0.0f);
226232

227233
for (int j = -a + 1; j <= a; j++) {
228234
for (int i = -a + 1; i <= a; i++) {
229235
int xi = kx1 + i;
230236
int yj = ky1 + j;
231-
half dx = half(srcX) - (half(kx1) + (half)i);
232-
half dy = half(srcY) - (half(ky1) + (half)j);
233-
half weight = lanczosWindow(dx, (half)lanczosFA) * lanczosWindow(dy, (half)lanczosFA);
237+
float dx = float(srcX) - (float(kx1) + (float)i);
238+
float dy = float(srcY) - (float(ky1) + (float)j);
239+
float weight = lanczosWindow(dx, lanczosFA) * lanczosWindow(dy, lanczosFA);
234240
weightSum += weight;
235241
for (int c = 0; c < components; ++c) {
236242
half clrf = castU16(reinterpret_cast<const uint16_t*>(src8 + clamp(yj, 0, inputHeight - 1) * srcStride)[clamp(xi, 0, inputWidth - 1)*components + c]);
237-
half clr = half(clrf * weight);
243+
float clr = (float)clrf * weight;
238244
rgb[c] += clr;
239245
}
240246
}
241247
}
242248

243249
for (int c = 0; c < components; ++c) {
244250
if (weightSum == 0) {
245-
dst16[x*components + c] = rgb[c].data_;
251+
dst16[x*components + c] = half(rgb[c]).data_;
246252
} else {
247-
dst16[x*components + c] = (rgb[c] / weightSum).data_;
253+
dst16[x*components + c] = half(rgb[c] / weightSum).data_;
248254
}
249255
}
250256
} else {
@@ -382,37 +388,39 @@ void scaleImageU16(uint16_t* input,
382388
dst16[x*components + c] += clr;
383389
}
384390
} else if (option == lanczos) {
385-
half rgb[components];
391+
float rgb[components];
392+
memset(&rgb[0], 0.0f, sizeof(float) * components);
386393

387-
int a = 3;
388-
half lanczosFA = half(3.0f);
394+
float lanczosFA = float(3.0f);
389395

390-
half weightSum(0.0f);
396+
int a = 3;
391397

392398
float kx1 = floor(srcX);
393399
float ky1 = floor(srcY);
394400

401+
float weightSum(0.0f);
402+
395403
for (int j = -a + 1; j <= a; j++) {
396404
for (int i = -a + 1; i <= a; i++) {
397405
int xi = kx1 + i;
398406
int yj = ky1 + j;
399-
half dx = half(srcX) - (half(kx1) + (half)i);
400-
half dy = half(srcY) - (half(ky1) + (half)j);
401-
half weight = lanczosWindow(dx, (half)lanczosFA) * lanczosWindow(dy, (half)lanczosFA);
407+
float dx = float(srcX) - (float(kx1) + (float)i);
408+
float dy = float(srcY) - (float(ky1) + (float)j);
409+
float weight = lanczosWindow(dx, (float)lanczosFA) * lanczosWindow(dy, (float)lanczosFA);
402410
weightSum += weight;
403411
for (int c = 0; c < components; ++c) {
404-
half clrf = PromoteToHalf(reinterpret_cast<const uint16_t*>(src8 + clamp(yj, 0, inputHeight - 1) * srcStride)[clamp(xi, 0, inputWidth - 1)*components + c], maxColors);
405-
half clr = half(clrf * weight);
412+
float clrf = PromoteTo<uint16_t, float>(reinterpret_cast<const uint16_t*>(src8 + clamp(yj, 0, inputHeight - 1) * srcStride)[clamp(xi, 0, inputWidth - 1)*components + c], maxColors);
413+
float clr = clrf * weight;
406414
rgb[c] += clr;
407415
}
408416
}
409417
}
410418

411419
for (int c = 0; c < components; ++c) {
412420
if (weightSum == 0) {
413-
dst16[x*components + c] = DemoteHalfTo<uint16_t>(rgb[c], maxColors);
421+
dst16[x*components + c] = DemoteTo<float, uint16_t>(rgb[c], maxColors);
414422
} else {
415-
dst16[x*components + c] = DemoteHalfTo<uint16_t>(rgb[c] / weightSum, maxColors);
423+
dst16[x*components + c] = DemoteTo<float, uint16_t>(rgb[c] / weightSum, maxColors);
416424
}
417425
}
418426
} else {
@@ -543,38 +551,39 @@ void scaleImageU8(uint8_t* input,
543551
dst[x*components + c] += clr;
544552
}
545553
} else if (option == lanczos) {
546-
half rgb[components];
554+
float rgb[components];
555+
memset(&rgb[0], 0.0f, sizeof(float) * components);
547556

548-
half lanczosFA = half(3.0f);
557+
float lanczosFA = float(3.0f);
549558

550559
int a = 3;
551560

552561
float kx1 = floor(srcX);
553562
float ky1 = floor(srcY);
554563

555-
half weightSum(0.0f);
564+
float weightSum(0.0f);
556565

557566
for (int j = -a + 1; j <= a; j++) {
558567
for (int i = -a + 1; i <= a; i++) {
559568
int xi = kx1 + i;
560569
int yj = ky1 + j;
561-
half dx = half(srcX) - (half(kx1) + (half)i);
562-
half dy = half(srcY) - (half(ky1) + (half)j);
563-
half weight = lanczosWindow(dx, (half)lanczosFA) * lanczosWindow(dy, (half)lanczosFA);
570+
float dx = float(srcX) - (float(kx1) + (float)i);
571+
float dy = float(srcY) - (float(ky1) + (float)j);
572+
float weight = lanczosWindow(dx, (float)lanczosFA) * lanczosWindow(dy, (float)lanczosFA);
564573
weightSum += weight;
565574
for (int c = 0; c < components; ++c) {
566-
half clrf = PromoteToHalf(reinterpret_cast<const uint8_t*>(src8 + clamp(yj, 0, inputHeight - 1) * srcStride)[clamp(xi, 0, inputWidth - 1)*components + c], maxColors);
567-
half clr = half(clrf * weight);
575+
float clrf = PromoteTo<uint8_t, float>(reinterpret_cast<const uint8_t*>(src8 + clamp(yj, 0, inputHeight - 1) * srcStride)[clamp(xi, 0, inputWidth - 1)*components + c], maxColors);
576+
float clr = clrf * weight;
568577
rgb[c] += clr;
569578
}
570579
}
571580
}
572581

573582
for (int c = 0; c < components; ++c) {
574583
if (weightSum == 0) {
575-
dst[x*components + c] = DemoteHalfTo<uint8_t>(rgb[c], maxColors);
584+
dst[x*components + c] = DemoteTo<float, uint8_t>(rgb[c], maxColors);
576585
} else {
577-
dst[x*components + c] = DemoteHalfTo<uint8_t>(rgb[c] / weightSum, maxColors);
586+
dst[x*components + c] = DemoteTo<float, uint8_t>(rgb[c] / weightSum, maxColors);
578587
}
579588
}
580589
} else {

0 commit comments

Comments
 (0)