Skip to content

Commit 84c1ab3

Browse files
committed
HDR images + other improvements
1 parent b9b7920 commit 84c1ab3

File tree

8 files changed

+46
-19
lines changed

8 files changed

+46
-19
lines changed

JxlCoder.podspec

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
Pod::Spec.new do |s|
22
s.name = 'JxlCoder'
3-
s.version = '1.0.3'
3+
s.version = '1.0.4'
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'
7-
s.license = { :type => 'BSD-3', :file => 'LICENSE' }
7+
s.license = { :type => 'CC0', :file => 'LICENSE' }
88
s.author = { 'username' => '[email protected]' }
99
s.source = { :git => 'https://github.com/awxkee/jxl-coder-swift.git', :tag => "#{s.version}" }
1010
s.ios.deployment_target = '11.0'

JxlNukePlugin.podspec

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
Pod::Spec.new do |s|
22
s.name = 'JxlNukePlugin'
3-
s.version = '1.0.1'
3+
s.version = '1.0.4'
44
s.summary = 'JXL encoder and decoder for SDWebImage'
55
s.description = 'JXL plugin for Nuke in iOS and MacOS'
66
s.homepage = 'https://github.com/awxkee/jxl-coder-swift'
7-
s.license = { :type => 'BSD-3', :file => 'LICENSE' }
7+
s.license = { :type => 'CC0', :file => 'LICENSE' }
88
s.author = { 'username' => '[email protected]' }
99
s.source = { :git => 'https://github.com/awxkee/jxl-coder-swift.git', :tag => "#{s.version}" }
1010
s.ios.deployment_target = '11.0'

JxlSDWebImageCoder.podspec

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
Pod::Spec.new do |s|
22
s.name = 'JxlSDWebImageCoder'
3-
s.version = '1.0.1'
3+
s.version = '1.0.4'
44
s.summary = 'JXL encoder and decoder for SDWebImage'
55
s.description = 'JXL plugin for SDWebImage in iOS and MacOS'
66
s.homepage = 'https://github.com/awxkee/jxl-coder-swift'
7-
s.license = { :type => 'BSD-3', :file => 'LICENSE' }
7+
s.license = { :type => 'CC0', :file => 'LICENSE' }
88
s.author = { 'username' => '[email protected]' }
99
s.source = { :git => 'https://github.com/awxkee/jxl-coder-swift.git', :tag => "#{s.version}" }
1010
s.ios.deployment_target = '11.0'

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ This package is provides support for JXL ( JPEG XL ) images for all apple platfo
55

66
A package to decode JXL on iOS, MacOS or encode JXL images. Also provider JXL support for Nuke and SDWebImage. Have support for older versions of iOS, MacOSX and all the simulators that doesn't have support for JXL images
77

8+
Supported ICC Profiles and HDR images.
9+
810
Package based on `libjxl`
911
</br>
1012
Main aim of the project is to use `JXL` image on all Apple platforms etc with usable speed and convenience

Sources/JxlCoder/JXLCoder.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public class JXLCoder {
2828
- Returns: If provided data is possible valid JXL image
2929
**/
3030
public static func isJXL(data: Data) throws -> Bool {
31-
return startsWith(magic1, ofLength: magic1.count, in: data) || startsWith(magic2, ofLength: magic1.count, in: data)
31+
return startsWith(magic1, ofLength: magic1.count, in: data) || startsWith(magic2, ofLength: magic2.count, in: data)
3232
}
3333

3434
/***

Sources/jxlc/JXLCPlusCoder.mm

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -205,8 +205,9 @@ - (nullable JXLSystemImage *)decode:(nonnull NSInputStream *)inputStream error:(
205205
auto dataWrapper = new JXLDataWrapper<uint8_t>();
206206
std::vector<uint8_t> iccProfile;
207207
size_t xSize, ySize;
208+
bool useFloats;
208209
auto decoded = DecodeJpegXlOneShot(imageData.data(), imageData.size(),
209-
&dataWrapper->data, &xSize, &ySize, &iccProfile);
210+
&dataWrapper->data, &xSize, &ySize, &iccProfile, &useFloats);
210211
if (!decoded) {
211212
delete dataWrapper;
212213
*error = [[NSError alloc] initWithDomain:@"JXLCoder" code:500 userInfo:@{ NSLocalizedDescriptionKey: @"Failed to decode JXL image" }];
@@ -226,9 +227,16 @@ - (nullable JXLSystemImage *)decode:(nonnull NSInputStream *)inputStream error:(
226227
colorSpace = CGColorSpaceCreateDeviceRGB();
227228
}
228229

229-
int flags = (int)kCGImageByteOrder32Big | (int)kCGImageAlphaLast;
230-
CGDataProviderRef provider = CGDataProviderCreateWithData(dataWrapper, dataWrapper->data.data(),
231-
dataWrapper->data.size(), JXLCGData8ProviderReleaseDataCallback);
230+
int flags;
231+
if (useFloats) {
232+
flags = (int)kCGImageByteOrder16Little | (int)kCGImageAlphaLast | (int)kCGBitmapFloatComponents;
233+
} else {
234+
flags = (int)kCGImageByteOrder32Big | (int)kCGImageAlphaLast;
235+
}
236+
CGDataProviderRef provider = CGDataProviderCreateWithData(dataWrapper,
237+
dataWrapper->data.data(),
238+
dataWrapper->data.size(),
239+
JXLCGData8ProviderReleaseDataCallback);
232240
if (!provider) {
233241
delete dataWrapper;
234242
*error = [[NSError alloc] initWithDomain:@"JXLCoder"
@@ -237,7 +245,9 @@ - (nullable JXLSystemImage *)decode:(nonnull NSInputStream *)inputStream error:(
237245
return NULL;
238246
}
239247

240-
CGImageRef imageRef = CGImageCreate(xSize, ySize, 8, 32, 4*xSize, colorSpace, flags, provider, NULL, false, kCGRenderingIntentDefault);
248+
CGImageRef imageRef = CGImageCreate(xSize, ySize, useFloats ? 16 : 8,
249+
useFloats ? 64 : 32, 4*xSize * (useFloats ? sizeof(uint16_t) : sizeof(uint8_t)),
250+
colorSpace, flags, provider, NULL, false, kCGRenderingIntentDefault);
241251
if (!imageRef) {
242252
*error = [[NSError alloc] initWithDomain:@"JXLCoder"
243253
code:500

Sources/jxlc/jxl_worker.cpp

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717

1818
bool DecodeJpegXlOneShot(const uint8_t *jxl, size_t size,
1919
std::vector<uint8_t> *pixels, size_t *xsize,
20-
size_t *ysize, std::vector<uint8_t> *icc_profile) {
20+
size_t *ysize, std::vector<uint8_t> *icc_profile,
21+
bool* useFloats) {
2122
// Multi-threaded parallel runner.
2223
auto runner = JxlResizableParallelRunnerMake(nullptr);
2324

@@ -36,10 +37,13 @@ bool DecodeJpegXlOneShot(const uint8_t *jxl, size_t size,
3637
}
3738

3839
JxlBasicInfo info;
39-
JxlPixelFormat format = {4, JXL_TYPE_UINT8, JXL_BIG_ENDIAN, 0};
40+
JxlPixelFormat format = {4, JXL_TYPE_UINT8, JXL_LITTLE_ENDIAN, 0};
4041

4142
JxlDecoderSetInput(dec.get(), jxl, size);
4243
JxlDecoderCloseInput(dec.get());
44+
int bitDepth = 8;
45+
*useFloats = false;
46+
bool hdrImage = false;
4347

4448
for (;;) {
4549
JxlDecoderStatus status = JxlDecoderProcessInput(dec.get());
@@ -54,6 +58,14 @@ bool DecodeJpegXlOneShot(const uint8_t *jxl, size_t size,
5458
}
5559
*xsize = info.xsize;
5660
*ysize = info.ysize;
61+
bitDepth = info.bits_per_sample;
62+
if (bitDepth > 8) {
63+
*useFloats = true;
64+
hdrImage = true;
65+
format = { 4, JXL_TYPE_FLOAT16, JXL_LITTLE_ENDIAN, 0 };
66+
} else {
67+
*useFloats = false;
68+
}
5769
JxlResizableParallelRunnerSetThreads(
5870
runner.get(),
5971
JxlResizableParallelRunnerSuggestThreads(info.xsize, info.ysize));
@@ -77,13 +89,15 @@ bool DecodeJpegXlOneShot(const uint8_t *jxl, size_t size,
7789
JxlDecoderImageOutBufferSize(dec.get(), &format, &buffer_size)) {
7890
return false;
7991
}
80-
if (buffer_size != *xsize * *ysize * 4 * sizeof(uint8_t)) {
92+
if (buffer_size != *xsize * *ysize * 4 * (hdrImage ? sizeof(uint16_t) : sizeof(uint8_t))) {
8193
return false;
8294
}
83-
pixels->resize(*xsize * *ysize * 4 * sizeof(uint8_t));
95+
pixels->resize(*xsize * *ysize * 4 * (hdrImage ? sizeof(uint16_t) : sizeof(uint8_t)));
8496
void *pixels_buffer = (void *) pixels->data();
85-
size_t pixels_buffer_size = pixels->size() * sizeof(uint8_t);
86-
if (JXL_DEC_SUCCESS != JxlDecoderSetImageOutBuffer(dec.get(), &format,
97+
size_t pixels_buffer_size = pixels->size() * (hdrImage ? sizeof(uint16_t) : sizeof(uint8_t));
98+
99+
if (JXL_DEC_SUCCESS != JxlDecoderSetImageOutBuffer(dec.get(),
100+
&format,
87101
pixels_buffer,
88102
pixels_buffer_size)) {
89103
return false;

Sources/jxlc/jxl_worker.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ enum jxl_compression_option {
2626

2727
bool DecodeJpegXlOneShot(const uint8_t *jxl, size_t size,
2828
std::vector<uint8_t> *pixels, size_t *xsize,
29-
size_t *ysize, std::vector<uint8_t> *icc_profile);
29+
size_t *ysize, std::vector<uint8_t> *icc_profile,
30+
bool* useFloats);
3031
bool DecodeBasicInfo(const uint8_t *jxl, size_t size, size_t *xsize, size_t *ysize);
3132
bool EncodeJxlOneshot(const std::vector<uint8_t> &pixels, const uint32_t xsize,
3233
const uint32_t ysize, std::vector<uint8_t> *compressed,

0 commit comments

Comments
 (0)