@@ -50,15 +50,20 @@ static inline float JXLGetDistance(const int quality)
5050 return (6 .24f +(float ) pow (2 .5f ,(30.0 -(float )quality)/5.0 )/6 .25f );
5151}
5252
53-
5453@implementation JxlInternalCoder
5554- (nullable NSData *)encode : (nonnull JXLSystemImage *)platformImage
56- colorSpace : (JXLColorSpace)colorSpace
57- compressionOption : (JXLCompressionOption)compressionOption
58- compressionDistance : (double )compressionDistance error : (NSError * _Nullable *_Nullable)error {
55+ colorSpace : (JXLColorSpace)colorSpace
56+ compressionOption : (JXLCompressionOption)compressionOption
57+ effort : (int )effort
58+ quality : (int )quality error : (NSError * _Nullable *_Nullable)error {
59+
60+ if (quality < 0 || quality > 100 ) {
61+ *error = [[NSError alloc ] initWithDomain: @" JXLCoder" code: 500 userInfo: @{ NSLocalizedDescriptionKey : @" Quality must be clamped in 0...100" }];
62+ return nil ;
63+ }
5964
60- if (compressionDistance < 0 || compressionDistance > 15 ) {
61- *error = [[NSError alloc ] initWithDomain: @" JXLCoder" code: 500 userInfo: @{ NSLocalizedDescriptionKey : @" Compression distance must be clamped in 0 ...15 " }];
65+ if (effort < 1 || effort > 9 ) {
66+ *error = [[NSError alloc ] initWithDomain: @" JXLCoder" code: 500 userInfo: @{ NSLocalizedDescriptionKey : @" Effort must be clamped in 1 ...9 " }];
6267 return nil ;
6368 }
6469
@@ -73,10 +78,10 @@ - (nullable NSData *)encode:(nonnull JXLSystemImage *)platformImage
7378 *error = [[NSError alloc ] initWithDomain: @" JXLCoder" code: 500 userInfo: @{ NSLocalizedDescriptionKey : @" Can' create preview of image" }];
7479 return nil ;
7580 }
76-
81+
7782 JxlPixelType jColorspace;
7883 JxlCompressionOption jCompressionOption;
79-
84+
8085 switch (colorSpace) {
8186 case kRGB :
8287 jColorspace = rgb;
@@ -85,7 +90,7 @@ - (nullable NSData *)encode:(nonnull JXLSystemImage *)platformImage
8590 jColorspace = rgba;
8691 break ;
8792 }
88-
93+
8994 switch (compressionOption) {
9095 case kLoseless :
9196 jCompressionOption = loseless;
@@ -97,7 +102,7 @@ - (nullable NSData *)encode:(nonnull JXLSystemImage *)platformImage
97102 std::vector<uint8_t > pixels;
98103 pixels.insert (pixels.end (), (uint8_t *)rgbaData, rgbaData + bufferSize);
99104 free (rgbaData);
100-
105+
101106 if (jColorspace == rgb) {
102107 auto resizedVector = [RgbRgbaConverter convertRGBAtoRGB: pixels width: width height: height];
103108 if (resizedVector.size () == 1 ) {
@@ -106,23 +111,23 @@ - (nullable NSData *)encode:(nonnull JXLSystemImage *)platformImage
106111 }
107112 pixels = resizedVector;
108113 }
109-
114+
110115 JXLDataWrapper<uint8_t >* wrapper = new JXLDataWrapper<uint8_t >();
111- auto encoded = EncodeJxlOneshot (pixels, width, height, &wrapper->data , jColorspace, jCompressionOption, compressionDistance );
116+ auto encoded = EncodeJxlOneshot (pixels, width, height, &wrapper->data , jColorspace, jCompressionOption, JXLGetDistance (quality), effort );
112117 if (!encoded) {
113118 delete wrapper;
114119 *error = [[NSError alloc ] initWithDomain: @" JXLCoder" code: 500 userInfo: @{ NSLocalizedDescriptionKey : @" Cannot encode JXL image" }];
115120 return nil ;
116121 }
117-
122+
118123 pixels.resize (1 );
119-
124+
120125 auto data = [[NSData alloc ] initWithBytesNoCopy: wrapper->data.data ()
121126 length: wrapper->data.size ()
122127 deallocator: ^(void * _Nonnull bytes, NSUInteger length) {
123128 delete wrapper;
124129 }];
125-
130+
126131 return data;
127132}
128133
@@ -133,7 +138,7 @@ - (CGSize)getSize:(nonnull NSInputStream *)inputStream error:(NSError *_Nullabl
133138 std::vector<uint8_t > imageData;
134139 [inputStream open ];
135140 if ([inputStream streamStatus ] == NSStreamStatusOpen) {
136-
141+
137142 while ([inputStream hasBytesAvailable ]) {
138143 NSInteger bytes_read = [inputStream read: buffer.data () maxLength: buffer_length];
139144 if (bytes_read > 0 ) {
@@ -154,19 +159,19 @@ - (CGSize)getSize:(nonnull NSInputStream *)inputStream error:(NSError *_Nullabl
154159 break ;
155160 }
156161 }
157-
162+
158163 [inputStream close ];
159164 } else {
160165 *error = [[NSError alloc ] initWithDomain: @" JXLCoder" code: 500 userInfo: @{ NSLocalizedDescriptionKey : @" Cannot open input stream" }];
161166 return CGSizeZero;
162167 }
163-
168+
164169 size_t width, height;
165170 if (!DecodeBasicInfo (imageData.data (), imageData.size (), &width, &height)) {
166171 *error = [[NSError alloc ] initWithDomain: @" JXLCoder" code: 500 userInfo: @{ NSLocalizedDescriptionKey : @" Cannot decode image info" }];
167172 return CGSizeZero;
168173 }
169-
174+
170175 return CGSizeMake (width, height);
171176}
172177
@@ -179,7 +184,7 @@ - (nullable JXLSystemImage *)decode:(nonnull NSInputStream *)inputStream
179184 std::vector<uint8_t > imageData;
180185 [inputStream open ];
181186 if ([inputStream streamStatus ] == NSStreamStatusOpen) {
182-
187+
183188 while ([inputStream hasBytesAvailable ]) {
184189 NSInteger bytes_read = [inputStream read: buffer.data () maxLength: buffer_length];
185190 if (bytes_read > 0 ) {
@@ -200,15 +205,15 @@ - (nullable JXLSystemImage *)decode:(nonnull NSInputStream *)inputStream
200205 break ;
201206 }
202207 }
203-
208+
204209 [inputStream close ];
205-
210+
206211 // Now you have the contents in the 'buffer' vector
207212 } else {
208213 *error = [[NSError alloc ] initWithDomain: @" JXLCoder" code: 500 userInfo: @{ NSLocalizedDescriptionKey : @" Cannot open input stream" }];
209214 return nil ;
210215 }
211-
216+
212217 std::vector<uint8_t > iccProfile;
213218 size_t xSize, ySize;
214219 bool useFloats;
@@ -223,15 +228,15 @@ - (nullable JXLSystemImage *)decode:(nonnull NSInputStream *)inputStream
223228 *error = [[NSError alloc ] initWithDomain: @" JXLCoder" code: 500 userInfo: @{ NSLocalizedDescriptionKey : @" Failed to decode JXL image" }];
224229 return nil ;
225230 }
226-
231+
227232 if (jxlExposedOrientation == Rotate90CW || jxlExposedOrientation == Rotate90CCW
228233 || jxlExposedOrientation == AntiTranspose
229234 || jxlExposedOrientation == OrientTranspose) {
230235 size_t xz = xSize;
231236 xSize = ySize;
232237 ySize = xz;
233238 }
234-
239+
235240 if (sampleSize.width > 0 && sampleSize.height > 0 ) {
236241 auto scaleResult = [RgbaScaler scaleData: outputData width: (int )xSize height: (int )ySize
237242 newWidth: (int )sampleSize.width newHeight: (int )sampleSize.height
@@ -243,7 +248,7 @@ - (nullable JXLSystemImage *)decode:(nonnull NSInputStream *)inputStream
243248 xSize = sampleSize.width ;
244249 ySize = sampleSize.height ;
245250 }
246-
251+
247252 CGColorSpaceRef colorSpace;
248253 if (iccProfile.size () > 0 ) {
249254 CFDataRef iccData = CFDataCreate (kCFAllocatorDefault , iccProfile.data (), iccProfile.size ());
@@ -252,13 +257,13 @@ - (nullable JXLSystemImage *)decode:(nonnull NSInputStream *)inputStream
252257 } else {
253258 colorSpace = CGColorSpaceCreateDeviceRGB ();
254259 }
255-
260+
256261 if (!colorSpace) {
257262 colorSpace = CGColorSpaceCreateDeviceRGB ();
258263 }
259-
264+
260265 int stride = components*(int )xSize * (int )(useFloats ? sizeof (uint16_t ) : sizeof (uint8_t ));
261-
266+
262267 int flags;
263268 if (useFloats) {
264269 flags = (int )kCGBitmapByteOrder16Host | (int )kCGBitmapFloatComponents ;
@@ -275,10 +280,10 @@ - (nullable JXLSystemImage *)decode:(nonnull NSInputStream *)inputStream
275280 flags |= (int )kCGImageAlphaNone ;
276281 }
277282 }
278-
283+
279284 auto dataWrapper = new JXLDataWrapper<uint8_t >();
280285 dataWrapper->data = outputData;
281-
286+
282287 CGDataProviderRef provider = CGDataProviderCreateWithData (dataWrapper,
283288 dataWrapper->data .data (),
284289 dataWrapper->data .size (),
@@ -290,10 +295,10 @@ - (nullable JXLSystemImage *)decode:(nonnull NSInputStream *)inputStream
290295 userInfo: @{ NSLocalizedDescriptionKey : @" CoreGraphics cannot allocate required provider" }];
291296 return NULL ;
292297 }
293-
298+
294299 int bitsPerComponent = (useFloats ? sizeof (uint16_t ) : sizeof (uint8_t )) * 8 ;
295300 int bitsPerPixel = bitsPerComponent*components;
296-
301+
297302 CGImageRef imageRef = CGImageCreate (xSize, ySize, bitsPerComponent,
298303 bitsPerPixel,
299304 stride,
@@ -310,7 +315,7 @@ - (nullable JXLSystemImage *)decode:(nonnull NSInputStream *)inputStream
310315#else
311316 image = [UIImage imageWithCGImage: imageRef scale: 1 orientation: UIImageOrientationUp];
312317#endif
313-
318+
314319 return image;
315320}
316321@end
0 commit comments