Skip to content

Commit 05dc878

Browse files
committed
added decoding speed
1 parent a4fd578 commit 05dc878

11 files changed

+82
-44
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.3.6'
3+
s.version = '1.4.0'
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/JxlCoder/JXLAnimatedEncoder.swift

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,31 +29,32 @@ import jxlc
2929
#endif
3030

3131
public class JXLAnimatedEncoder {
32-
32+
3333
private let enc: CJpegXLAnimatedEncoder
34-
34+
3535
public init(width: Int, height: Int,
3636
numLoops: Int = 0, // 0 - means infinity
3737
colorSpace: JXLColorSpace = .rgba,
3838
compressionOption: JXLCompressionOption = .lossy,
39-
effort: Int = 4, quality: Int = 0) throws {
39+
effort: Int = 4, quality: Int = 0, decodingSpeed: JXLEncoderDecodingSpeed = .slowest) throws {
4040
enc = try CJpegXLAnimatedEncoder(Int32(width),
4141
height: Int32(height),
4242
numLoops: Int32(numLoops),
4343
colorSpace: colorSpace,
4444
compressionOption: compressionOption,
4545
effort: Int32(effort),
46-
quality: Int32(quality))
46+
quality: Int32(quality),
47+
decodingSpeed: decodingSpeed)
4748
}
48-
49+
4950
/**
5051
- Parameter frame: all the frames must match provided width and height in constructor
5152
- Parameter duration: length of the frame in milliseconds
5253
*/
5354
public func add(frame: JXLPlatformImage, duration ms: Int) throws {
5455
try enc.addFrame(frame, duration: Int32(ms))
5556
}
56-
57+
5758
public func finish() throws -> Data {
5859
try enc.finish()
5960
}

Sources/JxlCoder/JXLCoder.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,11 +102,13 @@ public class JXLCoder {
102102
colorSpace: JXLColorSpace = .rgb,
103103
compressionOption: JXLCompressionOption = .lossy,
104104
effort: Int = 7,
105-
quality: Int = 0) throws -> Data {
105+
quality: Int = 0,
106+
decodingSpeed: JXLEncoderDecodingSpeed = .slowest) throws -> Data {
106107
return try shared.encode(image, colorSpace: colorSpace,
107108
compressionOption: compressionOption,
108109
effort: Int32(effort),
109-
quality: Int32(quality))
110+
quality: Int32(quality),
111+
decodingSpeed: decodingSpeed)
110112
}
111113

112114
/***

Sources/jxlc/CJpegXLAnimatedEncoder.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,11 @@
3131

3232
@interface CJpegXLAnimatedEncoder : NSObject
3333
-(nullable id)initWith:(int)width height:(int)height numLoops:(int)numLoops colorSpace:(JXLColorSpace)colorSpace
34-
compressionOption:(JXLCompressionOption)compressionOption
35-
effort:(int)effort
36-
quality:(int)quality error:(NSError * _Nullable *_Nullable)error;
34+
compressionOption:(JXLCompressionOption)compressionOption
35+
effort:(int)effort
36+
quality:(int)quality
37+
decodingSpeed:(JXLEncoderDecodingSpeed)decodingSpeed
38+
error:(NSError * _Nullable *_Nullable)error;
3739
-(nullable void*)addFrame:(nonnull JXLSystemImage *)platformImage duration:(int)duration error:(NSError * _Nullable *_Nullable)error;
3840
-(nullable NSData*)finish:(NSError * _Nullable *_Nullable)error;
3941
@end

Sources/jxlc/CJpegXLAnimatedEncoder.mm

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,9 @@ -(nullable id)initWith:(int)width height:(int)height
5050
colorSpace:(JXLColorSpace)colorSpace
5151
compressionOption:(JXLCompressionOption)compressionOption
5252
effort:(int)effort
53-
quality:(int)quality error:(NSError * _Nullable *_Nullable)error {
53+
quality:(int)quality
54+
decodingSpeed:(JXLEncoderDecodingSpeed)decodingSpeed
55+
error:(NSError * _Nullable *_Nullable)error {
5456
JxlPixelType jColorspace;
5557
JxlCompressionOption jCompressionOption;
5658

@@ -73,7 +75,7 @@ -(nullable id)initWith:(int)width height:(int)height
7375
}
7476

7577
try {
76-
enc = new JxlAnimatedEncoder(width, height, jColorspace, er8, jCompressionOption, numLoops, quality, effort);
78+
enc = new JxlAnimatedEncoder(width, height, jColorspace, er8, jCompressionOption, numLoops, quality, effort, (int)decodingSpeed);
7779
} catch (AnimatedEncoderError& err) {
7880
NSString *str = [[NSString alloc] initWithCString:err.what() encoding:NSUTF8StringEncoding];
7981
*error = [[NSError alloc] initWithDomain:@"JXLCoder" code:500 userInfo:@{ NSLocalizedDescriptionKey: str }];

Sources/jxlc/JXLSystemImage.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,14 @@ typedef NS_ENUM(NSInteger, JxlSampler) {
6767
kHann NS_SWIFT_NAME(hann)
6868
};
6969

70+
typedef NS_ENUM(NSInteger, JXLEncoderDecodingSpeed) {
71+
kSlowest NS_SWIFT_NAME(slowest) = 0,
72+
kSlow NS_SWIFT_NAME(slow) = 1,
73+
kMedium NS_SWIFT_NAME(medium) = 2,
74+
kFast NS_SWIFT_NAME(fast) = 3,
75+
kFastest NS_SWIFT_NAME(fastest) = 4
76+
};
77+
7078
@interface JXLSystemImage (JXLColorData)
7179
- (nullable uint8_t*)jxlRGBAPixels:(nonnull size_t*)bufferSize width:(nonnull int*)xSize height:(nonnull int*)ySize;
7280
@end

Sources/jxlc/JxlAnimatedEncoder.hpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ class JxlAnimatedEncoder {
5454
JxlAnimatedEncoder(int width, int height, JxlPixelType pixelType,
5555
JxlEncodingPixelFormat encodingPixelFormat,
5656
JxlCompressionOption compressionOption,
57-
int numLoops, int quality, int effort): width(width), height(height),
57+
int numLoops, int quality, int effort, int decodingSpeed): width(width), height(height),
5858
pixelType(pixelType), encodingPixelFormat(encodingPixelFormat),
5959
compressionOption(compressionOption), quality(quality), effort(effort) {
6060
if (!enc || !runner) {
@@ -166,6 +166,12 @@ class JxlAnimatedEncoder {
166166
throw AnimatedEncoderError(str);
167167
}
168168

169+
if (JXL_ENC_SUCCESS !=
170+
JxlEncoderFrameSettingsSetOption(frameSettings, JXL_ENC_FRAME_SETTING_DECODING_SPEED, decodingSpeed)) {
171+
std::string str = "Set decoding speed has failed";
172+
throw AnimatedEncoderError(str);
173+
}
174+
169175
if (pixelType == rgba) {
170176
if (JXL_ENC_SUCCESS !=
171177
JxlEncoderSetExtraChannelDistance(frameSettings, 0, JXLGetDistance(quality))) {

Sources/jxlc/JxlInternalCoder.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@
4343
colorSpace:(JXLColorSpace)colorSpace
4444
compressionOption:(JXLCompressionOption)compressionOption
4545
effort:(int)effort
46-
quality:(int)quality error:(NSError * _Nullable *_Nullable)error;
46+
quality:(int)quality
47+
decodingSpeed:(JXLEncoderDecodingSpeed)decodingSpeed
48+
error:(NSError * _Nullable *_Nullable)error;
4749
@end
4850

4951
#endif /* JXLCoder_h */

Sources/jxlc/JxlInternalCoder.mm

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -47,19 +47,21 @@ static inline float JXLGetDistance(const int quality)
4747
if (quality == 0)
4848
return(1.0f);
4949
float distance = quality >= 100 ? 0.0
50-
: quality >= 30
51-
? 0.1 + (100 - quality) * 0.09
52-
: 53.0 / 3000.0 * quality * quality -
53-
23.0 / 20.0 * quality + 25.0;
50+
: quality >= 30
51+
? 0.1 + (100 - quality) * 0.09
52+
: 53.0 / 3000.0 * quality * quality -
53+
23.0 / 20.0 * quality + 25.0;
5454
return distance;
5555
}
5656

5757
@implementation JxlInternalCoder
5858
- (nullable NSData *)encode:(nonnull JXLSystemImage *)platformImage
59-
colorSpace:(JXLColorSpace)colorSpace
60-
compressionOption:(JXLCompressionOption)compressionOption
61-
effort:(int)effort
62-
quality:(int)quality error:(NSError * _Nullable *_Nullable)error {
59+
colorSpace:(JXLColorSpace)colorSpace
60+
compressionOption:(JXLCompressionOption)compressionOption
61+
effort:(int)effort
62+
quality:(int)quality
63+
decodingSpeed:(JXLEncoderDecodingSpeed)decodingSpeed
64+
error:(NSError * _Nullable *_Nullable)error {
6365
try {
6466
if (quality < 0 || quality > 100) {
6567
*error = [[NSError alloc] initWithDomain:@"JXLCoder" code:500 userInfo:@{ NSLocalizedDescriptionKey: @"Quality must be clamped in 0...100" }];
@@ -117,7 +119,9 @@ - (nullable NSData *)encode:(nonnull JXLSystemImage *)platformImage
117119
}
118120

119121
JXLDataWrapper<uint8_t>* wrapper = new JXLDataWrapper<uint8_t>();
120-
auto encoded = EncodeJxlOneshot(pixels, width, height, &wrapper->data, jColorspace, jCompressionOption, JXLGetDistance(quality), effort);
122+
auto encoded = EncodeJxlOneshot(pixels, width, height, &wrapper->data,
123+
jColorspace, jCompressionOption, JXLGetDistance(quality),
124+
effort, (int)decodingSpeed);
121125
if (!encoded) {
122126
delete wrapper;
123127
*error = [[NSError alloc] initWithDomain:@"JXLCoder" code:500 userInfo:@{ NSLocalizedDescriptionKey: @"Cannot encode JXL image" }];
@@ -135,8 +139,8 @@ - (nullable NSData *)encode:(nonnull JXLSystemImage *)platformImage
135139
return data;
136140
} catch (std::bad_alloc &err) {
137141
*error = [[NSError alloc] initWithDomain:@"JXLCoder"
138-
code:500
139-
userInfo:@{ NSLocalizedDescriptionKey: [NSString stringWithFormat:@"Encoding image memory error: %s", err.what()] }];
142+
code:500
143+
userInfo:@{ NSLocalizedDescriptionKey: [NSString stringWithFormat:@"Encoding image memory error: %s", err.what()] }];
140144
return nullptr;
141145
}
142146
}
@@ -191,11 +195,11 @@ - (CGSize)getSize:(nonnull NSInputStream *)inputStream error:(NSError *_Nullable
191195
}
192196

193197
- (nullable JXLSystemImage *)decode:(nonnull NSInputStream *)inputStream
194-
rescale:(CGSize)rescale
195-
pixelFormat:(JXLPreferredPixelFormat)preferredPixelFormat
196-
sampler:(JxlSampler)sampler
197-
scale:(int)scale
198-
error:(NSError *_Nullable * _Nullable)error {
198+
rescale:(CGSize)rescale
199+
pixelFormat:(JXLPreferredPixelFormat)preferredPixelFormat
200+
sampler:(JxlSampler)sampler
201+
scale:(int)scale
202+
error:(NSError *_Nullable * _Nullable)error {
199203
try {
200204
int buffer_length = 30196;
201205
std::vector<uint8_t> buffer;
@@ -311,8 +315,8 @@ - (nullable JXLSystemImage *)decode:(nonnull NSInputStream *)inputStream
311315
}
312316

313317
auto scaleResult = [RgbaScaler scaleData:outputData width:(int)xSize height:(int)ySize
314-
newWidth:(int)rescale.width newHeight:(int)rescale.height
315-
components:components pixelFormat:useFloats ? kF16 : kU8 sampler:xSampler];
318+
newWidth:(int)rescale.width newHeight:(int)rescale.height
319+
components:components pixelFormat:useFloats ? kF16 : kU8 sampler:xSampler];
316320
if (!scaleResult) {
317321
*error = [[NSError alloc] initWithDomain:@"JXLCoder" code:500 userInfo:@{ NSLocalizedDescriptionKey: @"Rescale image has failed" }];
318322
return nil;
@@ -382,17 +386,17 @@ - (nullable JXLSystemImage *)decode:(nonnull NSInputStream *)inputStream
382386
return NULL;
383387
}
384388
JXLSystemImage *image = nil;
385-
#if JXL_PLUGIN_MAC
389+
#if JXL_PLUGIN_MAC
386390
image = [[NSImage alloc] initWithCGImage:imageRef size:CGSizeZero];
387-
#else
391+
#else
388392
image = [UIImage imageWithCGImage:imageRef scale:scale orientation:UIImageOrientationUp];
389-
#endif
393+
#endif
390394

391395
return image;
392396
} catch (std::bad_alloc &err) {
393-
*error = [[NSError alloc] initWithDomain:@"JXLCoder"
394-
code:500
395-
userInfo:@{ NSLocalizedDescriptionKey: [NSString stringWithFormat:@"Decoding image memory error: %s", err.what()] }];
397+
*error = [[NSError alloc] initWithDomain:@"JXLCoder"
398+
code:500
399+
userInfo:@{ NSLocalizedDescriptionKey: [NSString stringWithFormat:@"Decoding image memory error: %s", err.what()] }];
396400
return nullptr;
397401
}
398402
}

Sources/jxlc/JxlWorker.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -232,8 +232,11 @@ bool DecodeBasicInfo(const uint8_t *jxl, size_t size, size_t *xsize, size_t *ysi
232232
*/
233233
bool EncodeJxlOneshot(const std::vector<uint8_t> &pixels, const uint32_t xsize,
234234
const uint32_t ysize, std::vector<uint8_t> *compressed,
235-
JxlPixelType colorspace, JxlCompressionOption compressionOption,
236-
float compressionDistance, int effort) {
235+
JxlPixelType colorspace,
236+
JxlCompressionOption compressionOption,
237+
float compressionDistance,
238+
int effort,
239+
int decodingSpeed) {
237240
auto enc = JxlEncoderMake(nullptr);
238241
auto runner = JxlThreadParallelRunnerMake(nullptr,
239242
JxlThreadParallelRunnerDefaultNumWorkerThreads());
@@ -308,6 +311,11 @@ bool EncodeJxlOneshot(const std::vector<uint8_t> &pixels, const uint32_t xsize,
308311
return false;
309312
}
310313

314+
if (JXL_ENC_SUCCESS != JxlEncoderFrameSettingsSetOption(frameSettings,
315+
JXL_ENC_FRAME_SETTING_DECODING_SPEED, decodingSpeed)) {
316+
return false;
317+
}
318+
311319
if (JXL_ENC_SUCCESS !=
312320
JxlEncoderSetFrameDistance(frameSettings, compressionDistance)) {
313321
return false;

0 commit comments

Comments
 (0)