Advertisement
Guest User

Untitled

a guest
Feb 23rd, 2019
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.17 KB | None | 0 0
  1. PNG Signature Bytes: 89 50 4E 47 0D 0A 1A 0A
  2. File offset: 8
  3. IHDR length bytes: 00 00 00 04
  4. File offset: 12
  5. IHDR Chunktype bytes: 43 67 42 49
  6. File offset: 16
  7. IHDR Data byte: 50 00 20 02
  8. File offset: 20
  9. pngImageWidth: 1342185474
  10. pngImageWidth: 20480
  11. pngImageHeight: 8194
  12.  
  13. func anatomyOfPNGFile() {
  14. let bundle = Bundle.main
  15.  
  16. guard let pngFileUrl = bundle.url(forResource: "PNGFileSignature", withExtension: "png") else { fatalError() }
  17.  
  18. do {
  19. // Signature start------------------------------------------------------------------------------------------
  20.  
  21. let readFileHandle = try FileHandle(forReadingFrom: pngFileUrl)
  22. defer {
  23. readFileHandle.closeFile()
  24. }
  25. let pngSignatureData = readFileHandle.readData(ofLength: PNGFileAnatomyConstants.pngSignatureLength)
  26. let signatureString = pngSignatureData.hexEncodedString(options: [Data.HexEncodingOptions.upperCase])
  27. if signatureString != "89 50 4E 47 0D 0A 1A 0A " {
  28. fatalError(" Not a png")
  29. }
  30. print("PNG Signature Bytes: (signatureString)")
  31. print("File offset: (readFileHandle.offsetInFile)")
  32. // Signature ebd------------------------------------------------------------------------------------------
  33.  
  34.  
  35.  
  36.  
  37. // IHDR Length start------------------------------------------------------------------------------------------
  38. let ihdrLengthDataBigEndian = readFileHandle.readData(ofLength: PNGFileAnatomyConstants.ihdrLength)
  39.  
  40. let ihdrLength: UInt32
  41. if PlatformEndianess.isLittleEndian {
  42. ihdrLength = Data(ihdrLengthDataBigEndian.reversed()).withUnsafeBytes({ (unsafePointer: UnsafePointer<UInt32>) -> UInt32 in
  43. return unsafePointer.pointee
  44. })
  45. } else {
  46. ihdrLength = ihdrLengthDataBigEndian.withUnsafeBytes({ (unsafePointer: UnsafePointer<UInt32>) -> UInt32 in
  47. return unsafePointer.pointee
  48. })
  49. }
  50.  
  51. let ihdrLengthDataBigEndianString = ihdrLengthDataBigEndian.hexEncodedString(options: [.upperCase])
  52. print("IHDR length bytes: (ihdrLengthDataBigEndianString)")
  53. print("File offset: (readFileHandle.offsetInFile)")
  54. // IHDR Length end------------------------------------------------------------------------------------------
  55.  
  56.  
  57.  
  58.  
  59.  
  60. // IHDR chunk type start------------------------------------------------------------------------------------------
  61. let ihdrChunkTypeData = readFileHandle.readData(ofLength: PNGFileAnatomyConstants.chunkTypeLength)
  62. let ihdrChunkTypeDataString = ihdrChunkTypeData.hexEncodedString(options: [Data.HexEncodingOptions.upperCase])
  63. print("IHDR Chunktype bytes: (ihdrChunkTypeDataString)")
  64. print("File offset: (readFileHandle.offsetInFile)")
  65. // IHDR chunk type end------------------------------------------------------------------------------------------
  66.  
  67.  
  68.  
  69. // IHDR data byte start------------------------------------------------------------------------------------------
  70. let ihdrData = readFileHandle.readData(ofLength: Int(ihdrLength))
  71. let ihdrDataString = ihdrData.hexEncodedString(options: [.upperCase])
  72. print("IHDR Data byte: (ihdrDataString)")
  73. print("File offset: (readFileHandle.offsetInFile)")
  74. // IHDR data byte end------------------------------------------------------------------------------------------
  75.  
  76. do {
  77. let pngImageWidth: UInt32
  78. if PlatformEndianess.isLittleEndian {
  79. pngImageWidth = Data(ihdrData.reversed()).withUnsafeBytes({ (unsafePointer: UnsafePointer<UInt32>) -> UInt32 in
  80. return unsafePointer.pointee
  81. })
  82. } else {
  83. pngImageWidth = ihdrData.withUnsafeBytes({ (unsafePointer: UnsafePointer<UInt32>) -> UInt32 in
  84. return unsafePointer.pointee
  85. })
  86. }
  87.  
  88. print("pngImageWidth: (pngImageWidth)")
  89. }
  90.  
  91. do {
  92. let pngImageWidth: UInt16
  93. let widthData = Data(bytes: [ihdrData[0], ihdrData[1]])
  94. if PlatformEndianess.isLittleEndian {
  95.  
  96. pngImageWidth = Data(widthData.reversed()).withUnsafeBytes({ (unsafePointer: UnsafePointer<UInt16>) -> UInt16 in
  97. return unsafePointer.pointee
  98. })
  99. } else {
  100. pngImageWidth = widthData.withUnsafeBytes({ (unsafePointer: UnsafePointer<UInt16>) -> UInt16 in
  101. return unsafePointer.pointee
  102. })
  103. }
  104.  
  105. print("pngImageWidth: (pngImageWidth)")//20480
  106.  
  107. let pngImageHeight: UInt16
  108. let heightData = Data(bytes: [ihdrData[2], ihdrData[3]])
  109. if PlatformEndianess.isLittleEndian {
  110.  
  111. pngImageHeight = Data(heightData.reversed()).withUnsafeBytes({ (unsafePointer: UnsafePointer<UInt16>) -> UInt16 in
  112. return unsafePointer.pointee
  113. })
  114. } else {
  115. pngImageHeight = heightData.withUnsafeBytes({ (unsafePointer: UnsafePointer<UInt16>) -> UInt16 in
  116. return unsafePointer.pointee
  117. })
  118. }
  119.  
  120. print("pngImageHeight: (pngImageHeight)")//20480
  121. }
  122.  
  123. } catch {
  124. fatalError(error.localizedDescription)
  125. }
  126. }
  127.  
  128. extension Data {
  129. struct HexEncodingOptions: OptionSet {
  130. let rawValue: Int
  131. static let upperCase = HexEncodingOptions(rawValue: 1 << 0)
  132. }
  133.  
  134. func hexEncodedString(options: HexEncodingOptions = []) -> String {
  135. let hexDigits = Array((options.contains(.upperCase) ? "0123456789ABCDEF " : "0123456789abcdef ").utf16)
  136. var chars: [unichar] = []
  137. chars.reserveCapacity(3 * count)
  138. for byte in self {
  139. chars.append(hexDigits[Int(byte / 16)])
  140. chars.append(hexDigits[Int(byte % 16)])
  141. chars.append(hexDigits.last!)
  142. }
  143. return String(utf16CodeUnits: chars, count: chars.count)
  144. }
  145. }
  146.  
  147. class PlatformEndianess {
  148. static var isLittleEndian: Bool = {
  149. var integer: UInt16 = 0x0001
  150. return withUnsafeBytes(of: &integer, { (rawBufferPointer) -> Bool in
  151. return rawBufferPointer.first == 0x01
  152. })
  153. }()
  154. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement