SDWebImageDecoder.m 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. /*
  2. * This file is part of the SDWebImage package.
  3. * (c) Olivier Poitrey <rs@dailymotion.com>
  4. *
  5. * Created by james <https://github.com/mystcolor> on 9/28/11.
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. #import "SDWebImageDecoder.h"
  11. @implementation UIImage (ForceDecode)
  12. + (UIImage *)decodedImageWithImage:(UIImage *)image {
  13. if (image.images) {
  14. // Do not decode animated images
  15. return image;
  16. }
  17. CGImageRef imageRef = image.CGImage;
  18. CGSize imageSize = CGSizeMake(CGImageGetWidth(imageRef), CGImageGetHeight(imageRef));
  19. CGRect imageRect = (CGRect){.origin = CGPointZero, .size = imageSize};
  20. CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
  21. CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef);
  22. int infoMask = (bitmapInfo & kCGBitmapAlphaInfoMask);
  23. BOOL anyNonAlpha = (infoMask == kCGImageAlphaNone ||
  24. infoMask == kCGImageAlphaNoneSkipFirst ||
  25. infoMask == kCGImageAlphaNoneSkipLast);
  26. // CGBitmapContextCreate doesn't support kCGImageAlphaNone with RGB.
  27. // https://developer.apple.com/library/mac/#qa/qa1037/_index.html
  28. if (infoMask == kCGImageAlphaNone && CGColorSpaceGetNumberOfComponents(colorSpace) > 1) {
  29. // Unset the old alpha info.
  30. bitmapInfo &= ~kCGBitmapAlphaInfoMask;
  31. // Set noneSkipFirst.
  32. bitmapInfo |= kCGImageAlphaNoneSkipFirst;
  33. }
  34. // Some PNGs tell us they have alpha but only 3 components. Odd.
  35. else if (!anyNonAlpha && CGColorSpaceGetNumberOfComponents(colorSpace) == 3) {
  36. // Unset the old alpha info.
  37. bitmapInfo &= ~kCGBitmapAlphaInfoMask;
  38. bitmapInfo |= kCGImageAlphaPremultipliedFirst;
  39. }
  40. // It calculates the bytes-per-row based on the bitsPerComponent and width arguments.
  41. CGContextRef context = CGBitmapContextCreate(NULL,
  42. imageSize.width,
  43. imageSize.height,
  44. CGImageGetBitsPerComponent(imageRef),
  45. 0,
  46. colorSpace,
  47. bitmapInfo);
  48. CGColorSpaceRelease(colorSpace);
  49. // If failed, return undecompressed image
  50. if (!context) return image;
  51. CGContextDrawImage(context, imageRect, imageRef);
  52. CGImageRef decompressedImageRef = CGBitmapContextCreateImage(context);
  53. CGContextRelease(context);
  54. UIImage *decompressedImage = [UIImage imageWithCGImage:decompressedImageRef scale:image.scale orientation:image.imageOrientation];
  55. CGImageRelease(decompressedImageRef);
  56. return decompressedImage;
  57. }
  58. @end