FBImageUtils.m 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. /**
  2. * Copyright (c) 2015-present, Facebook, Inc.
  3. * All rights reserved.
  4. *
  5. * This source code is licensed under the BSD-style license found in the
  6. * LICENSE file in the root directory of this source tree. An additional grant
  7. * of patent rights can be found in the PATENTS file in the same directory.
  8. */
  9. #import "FBImageUtils.h"
  10. #import "FBMacros.h"
  11. #import "FBConfiguration.h"
  12. // https://en.wikipedia.org/wiki/List_of_file_signatures
  13. static uint8_t PNG_MAGIC[] = { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A };
  14. static const NSUInteger PNG_MAGIC_LEN = 8;
  15. static uint8_t JPG_MAGIC[] = { 0xff, 0xd8, 0xff };
  16. static const NSUInteger JPG_MAGIC_LEN = 3;
  17. BOOL FBIsPngImage(NSData *imageData)
  18. {
  19. if (nil == imageData || [imageData length] < PNG_MAGIC_LEN) {
  20. return NO;
  21. }
  22. static NSData* pngMagicStartData = nil;
  23. static dispatch_once_t oncePngToken;
  24. dispatch_once(&oncePngToken, ^{
  25. pngMagicStartData = [NSData dataWithBytesNoCopy:(void*)PNG_MAGIC length:PNG_MAGIC_LEN freeWhenDone:NO];
  26. });
  27. #pragma clang diagnostic push
  28. #pragma clang diagnostic ignored "-Wassign-enum"
  29. NSRange range = [imageData rangeOfData:pngMagicStartData options:kNilOptions range:NSMakeRange(0, PNG_MAGIC_LEN)];
  30. #pragma clang diagnostic pop
  31. return range.location != NSNotFound;
  32. }
  33. NSData *FBToPngData(NSData *imageData) {
  34. if (nil == imageData || [imageData length] < PNG_MAGIC_LEN) {
  35. return nil;
  36. }
  37. if (FBIsPngImage(imageData)) {
  38. return imageData;
  39. }
  40. UIImage *image = [UIImage imageWithData:imageData];
  41. return nil == image ? nil : (NSData *)UIImagePNGRepresentation(image);
  42. }
  43. BOOL FBIsJpegImage(NSData *imageData)
  44. {
  45. if (nil == imageData || [imageData length] < JPG_MAGIC_LEN) {
  46. return NO;
  47. }
  48. static NSData* jpgMagicStartData = nil;
  49. static dispatch_once_t onceJpgToken;
  50. dispatch_once(&onceJpgToken, ^{
  51. jpgMagicStartData = [NSData dataWithBytesNoCopy:(void*)JPG_MAGIC length:JPG_MAGIC_LEN freeWhenDone:NO];
  52. });
  53. #pragma clang diagnostic push
  54. #pragma clang diagnostic ignored "-Wassign-enum"
  55. NSRange range = [imageData rangeOfData:jpgMagicStartData options:kNilOptions range:NSMakeRange(0, JPG_MAGIC_LEN)];
  56. #pragma clang diagnostic pop
  57. return range.location != NSNotFound;
  58. }
  59. NSData *FBToJpegData(NSData *imageData, CGFloat compressionQuality) {
  60. if (nil == imageData || [imageData length] < JPG_MAGIC_LEN) {
  61. return nil;
  62. }
  63. if (FBIsJpegImage(imageData)) {
  64. return imageData;
  65. }
  66. UIImage *image = [UIImage imageWithData:imageData];
  67. return nil == image ? nil : (NSData *)UIImageJPEGRepresentation(image, compressionQuality);
  68. }