Posts

Post not yet marked as solved
10 Replies
6.1k Views
Hello,I am having an hard time figuring out how memory mapped files works under iOS. Suppose that I want to read a big file, let's say 4GB. If I use memory mapped files in READ mode I should be able to get a valid pointer to a file and benefit from the page fault mechanism of virtual memory but apparently iOS can map only up to 2.5GB of data. I run the following test on an iPad Pro A1673 that has 2GB of ram and got as result:2018-04-06 17:20:12.660888+0200 TestMemory[414:316466] Data address: 0x1022240002018-04-06 17:20:12.662355+0200 TestMemory[414:316466] Data address: 0x1122240002018-04-06 17:20:12.663801+0200 TestMemory[414:316466] Data address: 0x12b9000002018-04-06 17:20:12.665235+0200 TestMemory[414:316466] Data address: 0x13b9000002018-04-06 17:20:12.666756+0200 TestMemory[414:316466] Data address: 0x14b9000002018-04-06 17:20:12.668202+0200 TestMemory[414:316466] Data address: 0x15b9000002018-04-06 17:20:12.669597+0200 TestMemory[414:316466] Data address: 0x16ff240002018-04-06 17:20:12.739549+0200 TestMemory[414:316466] Data address: 0x1e00000002018-04-06 17:20:12.747604+0200 TestMemory[414:316466] Data address: 0x1f00000002018-04-06 17:20:12.749130+0200 TestMemory[414:316466] Data address: 0x2000000002018-04-06 17:20:12.764753+0200 TestMemory[414:316466] NSData failed: Error Domain=NSCocoaErrorDomain Code=256 "The file “02808580-5D42-43BC-B5AA-628E3682A546” couldn’t be opened." UserInfo={NSFilePath=/var/mobile/Containers/Data/Application/5207275C-5525-47CA-AC4B-2AA07E05C1E9/Documents/02808580-5D42-43BC-B5AA-628E3682A546, NSUnderlyingError=0x1c0455270 {Error Domain=NSPOSIXErrorDomain Code=12 "Cannot allocate memory"}}2018-04-06 17:20:12.764801+0200 TestMemory[414:316466] Mapped 2684354560- (NSString*)createFileOfSize:(unsigned long long)size { NSString* uuid = [[NSUUID UUID] UUIDString]; NSString* documentFolderPath = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject].path; NSString* filePath = [documentFolderPath stringByAppendingPathComponent:uuid]; NSFileHandle *fileHandle = [NSFileHandle fileHandleForWritingAtPath:filePath]; if (fileHandle == nil) { [[NSFileManager defaultManager] createFileAtPath:filePath contents:nil attributes:nil]; fileHandle = [NSFileHandle fileHandleForWritingAtPath:filePath]; } [fileHandle truncateFileAtOffset:size]; [fileHandle closeFile]; return filePath; } - (void)test { const unsigned long long MB = 1 << 20; const unsigned long long GB = 1 << 30; unsigned long long space = 4 * GB; unsigned long long size = 64 * MB; unsigned long long fileCount = space / size; NSMutableArray* mapped = [NSMutableArray array]; int i = 0; for (i = 0; i < fileCount; i++) { NSString* filePath = [self createFileOfSize:size]; NSError* error = nil; NSData* data = [NSData dataWithContentsOfFile:filePath options:NSDataReadingMappedAlways error:&error]; if (error) { NSLog(@"NSData failed: %@", error); break; } else { const void* bytes = [data bytes]; NSLog(@"Data address: %p", bytes); [mapped addObject:data]; } } NSLog(@"Mapped %llu", i * size); }Any idea of why we have this limitation?Thanks!Libe
Posted
by libe.
Last updated
.
Post not yet marked as solved
0 Replies
945 Views
Hello, I am trying to create an animated sequence of HEIC images but I cannot save the frame property duration. It seems this is a well know bug: https://github.com/SDWebImage/SDWebImage/issues/3120 The kCGImagePropertyHEICSDictionary is never saved. Here's a sample project to reproduce the bug: ImageIOHEICSEncodeDecodeBug.zip Has anybody managed to save this information in a HEIC sequence? Thanks! Here's how I am writing an reading the image sequence - (void)testHEICSBug {     // First, load an animated image (GIF)     // And you can change the type into png, which is an animated PNG format. Same result     NSData *GIFData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"image1" ofType:@"gif"]];     CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)GIFData, nil);     NSUInteger frameCount = CGImageSourceGetCount(source);     NSAssert(frameCount > 1, @"GIF frame count > 1");          // Split into frames array, encode to HEICS     NSMutableData *heicsData = [NSMutableData data];     CGImageDestinationRef destination = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)heicsData, (__bridge CFStringRef)AVFileTypeHEIC, frameCount, nil);               for (int i = 0; i < frameCount; i++) {         // First get the GIF input image and duration         CGImageRef cgImage = CGImageSourceCreateImageAtIndex(source, i, nil);         NSDictionary *inputProperties = (__bridge_transfer  NSDictionary *)CGImageSourceCopyPropertiesAtIndex(source, i, nil);         NSDictionary *inputDictionary = inputProperties[(__bridge NSString *)kCGImagePropertyGIFDictionary];         NSTimeInterval duration = [inputDictionary[(__bridge NSString *)kCGImagePropertyGIFUnclampedDelayTime] doubleValue];         NSAssert(cgImage, @"CGImage not nil");         NSAssert(duration > 0, @"Input duration > 0");                                    // Then, encode into HEICS animated image         NSMutableDictionary *outputDProperties = [NSMutableDictionary dictionary];         outputDProperties[(__bridge NSString *)kCGImagePropertyHEICSDictionary] = @{(__bridge NSString *)kCGImagePropertyHEICSUnclampedDelayTime : @(duration)};         CGImageDestinationAddImage(destination, cgImage, (__bridge_retained CFDictionaryRef)outputDProperties);     }          // Output HEICS image data     BOOL result = CGImageDestinationFinalize(destination);     NSAssert(result, @"Encode HEICS failed");               // Next, try to use ImageIO to decode HEICS and check duration          CGImageSourceRef newSource = CGImageSourceCreateWithData((__bridge CFDataRef)heicsData, nil);     frameCount = CGImageSourceGetCount(newSource);     NSAssert(frameCount > 1, @"New HEICS should be aniamted image");     NSUInteger frameIndex = 1; // I pick the 2nd frame, actually any frame contains this issue.     NSDictionary *newProperties = (__bridge_transfer NSDictionary *)CGImageSourceCopyPropertiesAtIndex(newSource, frameIndex, nil);     NSDictionary *newDictionary = newProperties[(__bridge NSString *)kCGImagePropertyHEICSDictionary];     NSTimeInterval newDuration = [newDictionary[(__bridge NSString *)kCGImagePropertyHEICSUnclampedDelayTime] doubleValue];     CGImageRef newImage = CGImageSourceCreateImageAtIndex(newSource, frameIndex, nil);          // Now, check the HEICS frame duration, however, it's nil :(     // Only image is kept.     NSAssert(newImage, @"frame image is not nil");     NSAssert(newDuration > 0, @"Decode the HEICS (which encoded from GIF) will loss the frame duration"); }
Posted
by libe.
Last updated
.
Post marked as solved
9 Replies
1.8k Views
Hello,I cannot get my thumbnail extension working under iOS12. I have created a new extension from Xcode 11 and linked the QuickLookThumbnailing framework as optional in the extension Link properties as it is not available under iOS12. The thumbnail extension works without issues under iOS13 but under iOS12 is never called. I also tried to link the QuickLook framework but I got the same result (extension not called).Did anyone manage to get the QuickLookThumbnailing framework working under iOS12?Thanks in advance for your help,Libero
Posted
by libe.
Last updated
.