Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- PNG Signature Bytes: 89 50 4E 47 0D 0A 1A 0A
- File offset: 8
- IHDR length bytes: 00 00 00 04
- File offset: 12
- IHDR Chunktype bytes: 43 67 42 49
- File offset: 16
- IHDR Data byte: 50 00 20 02
- File offset: 20
- pngImageWidth: 1342185474
- pngImageWidth: 20480
- pngImageHeight: 8194
- func anatomyOfPNGFile() {
- let bundle = Bundle.main
- guard let pngFileUrl = bundle.url(forResource: "PNGFileSignature", withExtension: "png") else { fatalError() }
- do {
- // Signature start------------------------------------------------------------------------------------------
- let readFileHandle = try FileHandle(forReadingFrom: pngFileUrl)
- defer {
- readFileHandle.closeFile()
- }
- let pngSignatureData = readFileHandle.readData(ofLength: PNGFileAnatomyConstants.pngSignatureLength)
- let signatureString = pngSignatureData.hexEncodedString(options: [Data.HexEncodingOptions.upperCase])
- if signatureString != "89 50 4E 47 0D 0A 1A 0A " {
- fatalError(" Not a png")
- }
- print("PNG Signature Bytes: (signatureString)")
- print("File offset: (readFileHandle.offsetInFile)")
- // Signature ebd------------------------------------------------------------------------------------------
- // IHDR Length start------------------------------------------------------------------------------------------
- let ihdrLengthDataBigEndian = readFileHandle.readData(ofLength: PNGFileAnatomyConstants.ihdrLength)
- let ihdrLength: UInt32
- if PlatformEndianess.isLittleEndian {
- ihdrLength = Data(ihdrLengthDataBigEndian.reversed()).withUnsafeBytes({ (unsafePointer: UnsafePointer<UInt32>) -> UInt32 in
- return unsafePointer.pointee
- })
- } else {
- ihdrLength = ihdrLengthDataBigEndian.withUnsafeBytes({ (unsafePointer: UnsafePointer<UInt32>) -> UInt32 in
- return unsafePointer.pointee
- })
- }
- let ihdrLengthDataBigEndianString = ihdrLengthDataBigEndian.hexEncodedString(options: [.upperCase])
- print("IHDR length bytes: (ihdrLengthDataBigEndianString)")
- print("File offset: (readFileHandle.offsetInFile)")
- // IHDR Length end------------------------------------------------------------------------------------------
- // IHDR chunk type start------------------------------------------------------------------------------------------
- let ihdrChunkTypeData = readFileHandle.readData(ofLength: PNGFileAnatomyConstants.chunkTypeLength)
- let ihdrChunkTypeDataString = ihdrChunkTypeData.hexEncodedString(options: [Data.HexEncodingOptions.upperCase])
- print("IHDR Chunktype bytes: (ihdrChunkTypeDataString)")
- print("File offset: (readFileHandle.offsetInFile)")
- // IHDR chunk type end------------------------------------------------------------------------------------------
- // IHDR data byte start------------------------------------------------------------------------------------------
- let ihdrData = readFileHandle.readData(ofLength: Int(ihdrLength))
- let ihdrDataString = ihdrData.hexEncodedString(options: [.upperCase])
- print("IHDR Data byte: (ihdrDataString)")
- print("File offset: (readFileHandle.offsetInFile)")
- // IHDR data byte end------------------------------------------------------------------------------------------
- do {
- let pngImageWidth: UInt32
- if PlatformEndianess.isLittleEndian {
- pngImageWidth = Data(ihdrData.reversed()).withUnsafeBytes({ (unsafePointer: UnsafePointer<UInt32>) -> UInt32 in
- return unsafePointer.pointee
- })
- } else {
- pngImageWidth = ihdrData.withUnsafeBytes({ (unsafePointer: UnsafePointer<UInt32>) -> UInt32 in
- return unsafePointer.pointee
- })
- }
- print("pngImageWidth: (pngImageWidth)")
- }
- do {
- let pngImageWidth: UInt16
- let widthData = Data(bytes: [ihdrData[0], ihdrData[1]])
- if PlatformEndianess.isLittleEndian {
- pngImageWidth = Data(widthData.reversed()).withUnsafeBytes({ (unsafePointer: UnsafePointer<UInt16>) -> UInt16 in
- return unsafePointer.pointee
- })
- } else {
- pngImageWidth = widthData.withUnsafeBytes({ (unsafePointer: UnsafePointer<UInt16>) -> UInt16 in
- return unsafePointer.pointee
- })
- }
- print("pngImageWidth: (pngImageWidth)")//20480
- let pngImageHeight: UInt16
- let heightData = Data(bytes: [ihdrData[2], ihdrData[3]])
- if PlatformEndianess.isLittleEndian {
- pngImageHeight = Data(heightData.reversed()).withUnsafeBytes({ (unsafePointer: UnsafePointer<UInt16>) -> UInt16 in
- return unsafePointer.pointee
- })
- } else {
- pngImageHeight = heightData.withUnsafeBytes({ (unsafePointer: UnsafePointer<UInt16>) -> UInt16 in
- return unsafePointer.pointee
- })
- }
- print("pngImageHeight: (pngImageHeight)")//20480
- }
- } catch {
- fatalError(error.localizedDescription)
- }
- }
- extension Data {
- struct HexEncodingOptions: OptionSet {
- let rawValue: Int
- static let upperCase = HexEncodingOptions(rawValue: 1 << 0)
- }
- func hexEncodedString(options: HexEncodingOptions = []) -> String {
- let hexDigits = Array((options.contains(.upperCase) ? "0123456789ABCDEF " : "0123456789abcdef ").utf16)
- var chars: [unichar] = []
- chars.reserveCapacity(3 * count)
- for byte in self {
- chars.append(hexDigits[Int(byte / 16)])
- chars.append(hexDigits[Int(byte % 16)])
- chars.append(hexDigits.last!)
- }
- return String(utf16CodeUnits: chars, count: chars.count)
- }
- }
- class PlatformEndianess {
- static var isLittleEndian: Bool = {
- var integer: UInt16 = 0x0001
- return withUnsafeBytes(of: &integer, { (rawBufferPointer) -> Bool in
- return rawBufferPointer.first == 0x01
- })
- }()
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement