Custom jpeg xl loader

This commit is contained in:
Ali 2023-08-24 23:31:24 +04:00
parent 6a9abb1a9c
commit 8964f8c3d4
4 changed files with 36 additions and 11 deletions

View File

@ -103,7 +103,8 @@ private let internalMimePrefixes: [String] = [
"image/jpeg", "image/jpeg",
"image/jpg", "image/jpg",
"image/png", "image/png",
"image/heic" "image/heic",
"image/jxl"
] ]
public func internalDocumentItemSupportsMimeType(_ type: String, fileName: String?) -> Bool { public func internalDocumentItemSupportsMimeType(_ type: String, fileName: String?) -> Bool {

View File

@ -197,10 +197,10 @@ UIImage * _Nullable decompressJPEGXLData(NSData * _Nonnull data) {
if (JXL_DEC_SUCCESS != JxlDecoderImageOutBufferSize(dec.get(), &format, &buffer_size)) { if (JXL_DEC_SUCCESS != JxlDecoderImageOutBufferSize(dec.get(), &format, &buffer_size)) {
return nil; return nil;
} }
if (buffer_size != xsize * ysize * 16) { if (buffer_size != xsize * ysize * 4) {
return nil; //return nil;
} }
pixels.resize(xsize * ysize * 4); pixels.resize(buffer_size);
void* pixels_buffer = (void*)pixels.data(); void* pixels_buffer = (void*)pixels.data();
size_t pixels_buffer_size = pixels.size() * sizeof(float); size_t pixels_buffer_size = pixels.size() * sizeof(float);
if (JXL_DEC_SUCCESS != JxlDecoderSetImageOutBuffer(dec.get(), &format, pixels_buffer, pixels_buffer_size)) { if (JXL_DEC_SUCCESS != JxlDecoderSetImageOutBuffer(dec.get(), &format, pixels_buffer, pixels_buffer_size)) {
@ -214,11 +214,28 @@ UIImage * _Nullable decompressJPEGXLData(NSData * _Nonnull data) {
// It's not required to call JxlDecoderReleaseInput(dec.get()) here since // It's not required to call JxlDecoderReleaseInput(dec.get()) here since
// the decoder will be destroyed. // the decoder will be destroyed.
int targetBytesPerRow = xsize * 4; int width = xsize;
uint8_t *permuteTargetBuffer = (uint8_t *)malloc(targetBytesPerRow * ysize); int height = ysize;
memcpy(permuteTargetBuffer, pixels.data(), pixels.size()); int sourceBytesPerRow = width * 4;
int targetBytesPerRow = width * 4;
NSData *resultData = [[NSData alloc] initWithBytesNoCopy:permuteTargetBuffer length:targetBytesPerRow * ysize deallocator:^(void * _Nonnull bytes, __unused NSUInteger length) { vImage_Buffer source;
source.width = width;
source.height = height;
source.rowBytes = sourceBytesPerRow;
source.data = pixels.data();
vImage_Buffer permuteTarget;
permuteTarget.width = width;
permuteTarget.height = height;
permuteTarget.rowBytes = targetBytesPerRow;
unsigned char *permuteTargetBuffer = (uint8_t *)malloc(targetBytesPerRow * height);
permuteTarget.data = permuteTargetBuffer;
const uint8_t permuteMap[4] = {2,1,0,3};
vImagePermuteChannels_ARGB8888(&source, &permuteTarget, permuteMap, kvImageDoNotTile);
NSData *resultData = [[NSData alloc] initWithBytesNoCopy:permuteTargetBuffer length:targetBytesPerRow * height deallocator:^(void * _Nonnull bytes, __unused NSUInteger length) {
free(bytes); free(bytes);
}]; }];
@ -235,7 +252,7 @@ UIImage * _Nullable decompressJPEGXLData(NSData * _Nonnull data) {
UIGraphicsEndImageContext(); UIGraphicsEndImageContext();
}); });
CGImageRef cgImg = CGImageCreate(xsize, ysize, 8, 32, targetBytesPerRow, imageColorSpace, bitmapInfo, dataProvider, NULL, true, kCGRenderingIntentDefault); CGImageRef cgImg = CGImageCreate(width, height, 8, 32, targetBytesPerRow, imageColorSpace, bitmapInfo, dataProvider, NULL, true, kCGRenderingIntentDefault);
CGDataProviderRelease(dataProvider); CGDataProviderRelease(dataProvider);

View File

@ -26,6 +26,7 @@ swift_library(
"//submodules/MusicAlbumArtResources:MusicAlbumArtResources", "//submodules/MusicAlbumArtResources:MusicAlbumArtResources",
"//submodules/Svg:Svg", "//submodules/Svg:Svg",
"//submodules/Utils/RangeSet:RangeSet", "//submodules/Utils/RangeSet:RangeSet",
"//submodules/ImageCompression",
], ],
visibility = [ visibility = [
"//visibility:public", "//visibility:public",

View File

@ -20,7 +20,7 @@ import MusicAlbumArtResources
import Svg import Svg
import RangeSet import RangeSet
import Accelerate import Accelerate
import ImageCompression
private enum ResourceFileData { private enum ResourceFileData {
case data(Data) case data(Data)
@ -2292,6 +2292,12 @@ public func chatMessageImageFile(account: Account, userLocation: MediaResourceUs
} }
} }
} }
if fullSizeImage == nil, fileReference.media.mimeType == "image/jxl" {
if let data = try? Data(contentsOf: URL(fileURLWithPath: fullSizePath), options: [.mappedIfSafe]), let image = decompressImageFromJPEGXL(data: data) {
fullSizeImage = image.cgImage
}
}
} }
var thumbnailImage: CGImage? var thumbnailImage: CGImage?