Skip to content

Commit cb60c1a

Browse files
committed
added subsampling
1 parent de32c9e commit cb60c1a

File tree

7 files changed

+365
-11
lines changed

7 files changed

+365
-11
lines changed

.swiftpm/xcode/xcuserdata/radzivonbartoshyk.xcuserdatad/xcschemes/xcschememanagement.plist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
<key>JxlCoder.xcscheme_^#shared#^_</key>
1818
<dict>
1919
<key>orderHint</key>
20-
<integer>0</integer>
20+
<integer>1</integer>
2121
</dict>
2222
<key>jxlcoder.xcscheme_^#shared#^_</key>
2323
<dict>

Sources/JxlCoder/JXLCoder.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,27 +34,27 @@ public class JXLCoder {
3434
/***
3535
- Returns: Decoded JXL image if this is the valid one
3636
**/
37-
public static func decode(srcStream: InputStream) throws -> JXLPlatformImage {
38-
return try shared.decode(srcStream)
37+
public static func decode(srcStream: InputStream, sampleSize: CGSize = .zero) throws -> JXLPlatformImage {
38+
return try shared.decode(srcStream, sampleSize: sampleSize)
3939
}
4040

4141
/***
4242
- Returns: Decoded JXL image if this is the valid one
4343
**/
44-
public static func decode(url: URL) throws -> JXLPlatformImage {
44+
public static func decode(url: URL, sampleSize: CGSize = .zero) throws -> JXLPlatformImage {
4545
guard let srcStream = InputStream(url: url) else {
4646
throw NSError(domain: "JXLCoder", code: 500,
4747
userInfo: [NSLocalizedDescriptionKey: "JXLCoder cannot open provided URL"])
4848
}
49-
return try shared.decode(srcStream)
49+
return try shared.decode(srcStream, sampleSize: sampleSize)
5050
}
5151

5252
/***
5353
- Returns: Decoded JXL image if this is the valid one
5454
**/
55-
public static func decode(data: Data) throws -> JXLPlatformImage {
55+
public static func decode(data: Data, sampleSize: CGSize = .zero) throws -> JXLPlatformImage {
5656
let srcStream = InputStream(data: data)
57-
return try shared.decode(srcStream)
57+
return try shared.decode(srcStream, sampleSize: sampleSize)
5858
}
5959

6060
/***

Sources/jxlc/JxlInternalCoder.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ typedef NS_ENUM(NSInteger, JXLCompressionOption) {
4040
};
4141

4242
@interface JxlInternalCoder: NSObject
43-
- (nullable JXLSystemImage *)decode:(nonnull NSInputStream *)inputStream error:(NSError *_Nullable * _Nullable)error;
43+
- (nullable JXLSystemImage *)decode:(nonnull NSInputStream *)inputStream sampleSize:(CGSize)sampleSize error:(NSError *_Nullable * _Nullable)error;
4444
- (CGSize)getSize:(nonnull NSInputStream *)inputStream error:(NSError *_Nullable * _Nullable)error;
4545
- (nullable NSData *)encode:(nonnull JXLSystemImage *)platformImage
4646
colorSpace:(JXLColorSpace)colorSpace

Sources/jxlc/JxlInternalCoder.mm

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#import "JxlWorker.hpp"
3030
#import <Accelerate/Accelerate.h>
3131
#import "RgbRgbaConverter.hpp"
32+
#import "RgbaScaler.h"
3233

3334
static void JXLCGData16ProviderReleaseDataCallback(void *info, const void *data, size_t size) {
3435
auto dataWrapper = static_cast<JXLDataWrapper<uint16_t>*>(info);
@@ -160,7 +161,9 @@ - (CGSize)getSize:(nonnull NSInputStream *)inputStream error:(NSError *_Nullabl
160161
return CGSizeMake(width, height);
161162
}
162163

163-
- (nullable JXLSystemImage *)decode:(nonnull NSInputStream *)inputStream error:(NSError *_Nullable * _Nullable)error {
164+
- (nullable JXLSystemImage *)decode:(nonnull NSInputStream *)inputStream
165+
sampleSize:(CGSize)sampleSize
166+
error:(NSError *_Nullable * _Nullable)error {
164167
int buffer_length = 30196;
165168
std::vector<uint8_t> buffer;
166169
buffer.resize(buffer_length);
@@ -212,6 +215,17 @@ - (nullable JXLSystemImage *)decode:(nonnull NSInputStream *)inputStream error:(
212215
return nil;
213216
}
214217

218+
if (sampleSize.width > 0 && sampleSize.height > 0) {
219+
auto scaleResult = [RgbaScaler scaleData:outputData width:(int)xSize height:(int)ySize
220+
newWidth:(int)sampleSize.width newHeight:(int)sampleSize.height
221+
components:components pixelFormat:useFloats ? kF16 : kU8];
222+
if (!scaleResult) {
223+
*error = [[NSError alloc] initWithDomain:@"JXLCoder" code:500 userInfo:@{ NSLocalizedDescriptionKey: @"Rescale image has failed" }];
224+
return nil;
225+
}
226+
xSize = sampleSize.width;
227+
ySize = sampleSize.height;
228+
}
215229

216230
CGColorSpaceRef colorSpace;
217231
if (iccProfile.size() > 0) {

Sources/jxlc/JxlWorker.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ bool DecodeJpegXlOneShot(const uint8_t *jxl, size_t size,
6262
JxlDecoderSetUnpremultiplyAlpha(dec.get(), JXL_TRUE);
6363

6464
JxlBasicInfo info;
65-
JxlPixelFormat format = {4, JXL_TYPE_UINT8, JXL_LITTLE_ENDIAN, 0};
65+
JxlPixelFormat format = {4, JXL_TYPE_UINT8, JXL_NATIVE_ENDIAN, 0};
6666

6767
JxlDecoderSetInput(dec.get(), jxl, size);
6868
JxlDecoderCloseInput(dec.get());
@@ -98,7 +98,7 @@ bool DecodeJpegXlOneShot(const uint8_t *jxl, size_t size,
9898
if (bitDepth > 8) {
9999
*useFloats = true;
100100
hdrImage = true;
101-
format = { static_cast<uint32_t>(baseComponents), JXL_TYPE_FLOAT16, JXL_LITTLE_ENDIAN, 0 };
101+
format = { static_cast<uint32_t>(baseComponents), JXL_TYPE_FLOAT16, JXL_NATIVE_ENDIAN, 0 };
102102
} else {
103103
format.num_channels = baseComponents;
104104
*useFloats = false;

Sources/jxlc/RgbaScaler.h

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
//
2+
// RgbaScaler.h
3+
// JxclCoder [https://github.com/awxkee/jxl-coder-swift]
4+
//
5+
// Created by Radzivon Bartoshyk on 27/09/2023.
6+
//
7+
// Permission is hereby granted, free of charge, to any person obtaining a copy
8+
// of this software and associated documentation files (the "Software"), to deal
9+
// in the Software without restriction, including without limitation the rights
10+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
// copies of the Software, and to permit persons to whom the Software is
12+
// furnished to do so, subject to the following conditions:
13+
//
14+
// The above copyright notice and this permission notice shall be included in
15+
// all copies or substantial portions of the Software.
16+
//
17+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23+
// THE SOFTWARE.
24+
//
25+
26+
#ifndef RgbaScaler_h
27+
#define RgbaScaler_h
28+
29+
#ifdef __cplusplus
30+
31+
#import <vector>
32+
33+
typedef NS_ENUM(NSInteger, JxlIPixelFormat) {
34+
kU8 NS_SWIFT_NAME(Uniform8),
35+
kF16 NS_SWIFT_NAME(Float16)
36+
};
37+
38+
@interface RgbaScaler : NSObject
39+
/**
40+
* Converts unsigned uint8_t RGBA to RGB in uint8_t.
41+
* @author Radzivon Bartoshyk
42+
*
43+
* @param srcVector Source buffer
44+
* @param width width of of the image
45+
* @param height width of of the image
46+
* @param pixelFormat Pixel Format of the image
47+
* @return destination
48+
*/
49+
+(bool) scaleData:(std::vector<uint8_t>&)src width:(int)width height:(int)height newWidth:(int)newWidth newHeight:(int)newHeight components:(int)components pixelFormat:(JxlIPixelFormat)pixelFormat;
50+
@end
51+
52+
#endif
53+
54+
#endif /* Header_h */

0 commit comments

Comments
 (0)