TwitterImagePipeline/TIPImageCodecs.m (100 lines of code) (raw):

// // TIPImageCodecs.m // TwitterImagePipeline // // Created on 11/7/16. // Copyright © 2020 Twitter. All rights reserved. // #import "TIP_Project.h" #import "TIPError.h" #import "TIPImageCodecs.h" NS_ASSUME_NONNULL_BEGIN TIPImageContainer * __nullable TIPDecodeImageFromData(id<TIPImageCodec> codec, id __nullable config, NSData *imageData, CGSize targetDimensions, UIViewContentMode targetContentMode) __attribute__((overloadable)) { return TIPDecodeImageFromData(codec, config, imageData, targetDimensions, targetContentMode, nil); } TIPImageContainer * __nullable TIPDecodeImageFromData(id<TIPImageCodec> codec, id __nullable config, NSData *imageData, CGSize targetDimensions, UIViewContentMode targetContentMode, NSString * __nullable earlyGuessImageType) __attribute__((overloadable)) { TIPImageContainer *container = nil; id<TIPImageDecoder> decoder = codec.tip_decoder; if ([decoder respondsToSelector:@selector(tip_decodeImageWithData:targetDimensions:targetContentMode:config:)]) { container = [decoder tip_decodeImageWithData:imageData targetDimensions:targetDimensions targetContentMode:targetContentMode config:config]; } else if ([decoder respondsToSelector:@selector(tip_decodeImageWithData:config:)]) { TIPLogWarning(@"%@ implements legacy %@, needs to be updated to implement modern %@ method", decoder, NSStringFromSelector(@selector(tip_decodeImageWithData:config:)), NSStringFromSelector(@selector(tip_decodeImageWithData:targetDimensions:targetContentMode:config:))); #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" container = [decoder tip_decodeImageWithData:imageData config:config]; #pragma clang diagnostic pop } else { const TIPImageDecoderDetectionResult result = [decoder tip_detectDecodableData:imageData isCompleteData:YES earlyGuessImageType:earlyGuessImageType]; if (TIPImageDecoderDetectionResultMatch == result) { id<TIPImageDecoderContext> context = [decoder tip_initiateDecoding:config expectedDataLength:imageData.length buffer:nil]; [decoder tip_append:context data:imageData]; if (TIPImageDecoderAppendResultDidCompleteLoading == [decoder tip_finalizeDecoding:context]) { container = [decoder tip_renderImage:context renderMode:TIPImageDecoderRenderModeCompleteImage targetDimensions:targetDimensions targetContentMode:targetContentMode]; } } } return container; } BOOL TIPEncodeImageToFile(id<TIPImageCodec> codec, TIPImageContainer *imageContainer, NSString *filePath, TIPImageEncodingOptions options, float quality, BOOL atomic, NSError * __autoreleasing __nullable * __nullable error) { BOOL success = NO; id<TIPImageEncoder> encoder = codec.tip_encoder; if (!encoder) { if (error) { *error = [NSError errorWithDomain:TIPErrorDomain code:TIPErrorCodeEncodingUnsupported userInfo:@{ @"codec" : codec }]; } } else { if ([encoder respondsToSelector:@selector(tip_writeToFile:withImage:encodingOptions:suggestedQuality:atomically:error:)]) { success = [encoder tip_writeToFile:filePath withImage:imageContainer encodingOptions:options suggestedQuality:quality atomically:atomic error:error]; } else { NSData *data = [encoder tip_writeDataWithImage:imageContainer encodingOptions:options suggestedQuality:quality error:error]; if (data) { success = [data writeToFile:filePath options:(atomic) ? NSDataWritingAtomic : 0 error:error]; } } } if (!success && error) { TIPAssert(*error != nil); if (!*error) { *error = [NSError errorWithDomain:TIPErrorDomain code:TIPErrorCodeUnknown userInfo:nil]; } } return success; } NS_ASSUME_NONNULL_END