read_ipa 0.0.3 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/read_ipa.rb +33 -11
- metadata +30 -3
- data/lib/read_ipa/png_file.rb +0 -113
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 648e457c45f8e39dfcb492df5565274878225573
|
4
|
+
data.tar.gz: 9274380e7df40a0108f61f176f102762bca3ec29
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3a405bbc23f2bec232ca790e4e8074a25204e8949a0f31b76fc208e04ebaa93e522c0ddeebf31cba4bc75f4de4d749d048d024a3f7e236da63e19dcc9b75edfd
|
7
|
+
data.tar.gz: 56a3d52489279132673d92ead33ef86b3e64c065dd8124748d6a913ba92bcc724fb30b21089e8b1696754c811711426401ebc07be16e36cd090f69cdeecb53e2
|
data/lib/read_ipa.rb
CHANGED
@@ -6,7 +6,8 @@ rescue LoadError
|
|
6
6
|
end
|
7
7
|
|
8
8
|
require 'read_ipa/plist_binary'
|
9
|
-
require '
|
9
|
+
require 'apple_png'
|
10
|
+
require 'chunky_png'
|
10
11
|
|
11
12
|
module ReadIpa
|
12
13
|
class IpaFile
|
@@ -48,20 +49,41 @@ module ReadIpa
|
|
48
49
|
end
|
49
50
|
end
|
50
51
|
|
52
|
+
def read_png(data)
|
53
|
+
begin
|
54
|
+
return ApplePng.new(data)
|
55
|
+
rescue NotValidApplePngError
|
56
|
+
return ChunkyPng::Image.from_datastream(data)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def get_highest_res_icon(icons_array)
|
61
|
+
highest_res_icon = icons_array
|
62
|
+
.map{ |icon_path| icon_path.downcase.end_with?('.png') ? icon_path : icon_path + '.png' }
|
63
|
+
.map{ |icon_path| read_file(icon_path) }
|
64
|
+
.max_by{|data| read_png(data).width }
|
65
|
+
|
66
|
+
begin
|
67
|
+
return ApplePng.new(highest_res_icon).data
|
68
|
+
rescue NotValidApplePngError
|
69
|
+
highest_res_icon
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
51
73
|
def icon_file
|
52
74
|
if plist["CFBundleIconFiles"]
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
75
|
+
get_highest_res_icon(plist["CFBundleIconFiles"])
|
76
|
+
elsif plist["CFBundleIcons"]
|
77
|
+
dict = plist["CFBundleIcons"]
|
78
|
+
primary_icons = dict["CFBundlePrimaryIcon"]
|
79
|
+
return nil unless primary_icons
|
80
|
+
icons = primary_icons.to_rb["CFBundleIconFiles"]
|
81
|
+
return nil unless icons
|
82
|
+
get_highest_res_icon(icons)
|
61
83
|
elsif plist["CFBundleIconFile"]
|
62
84
|
data = read_file(plist["CFBundleIconFile"])
|
63
|
-
png =
|
64
|
-
png.
|
85
|
+
png = ApplePng.new(data)
|
86
|
+
png.data
|
65
87
|
else
|
66
88
|
nil
|
67
89
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: read_ipa
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marvin Killing
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-06-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -66,6 +66,34 @@ dependencies:
|
|
66
66
|
- - '='
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: 2.1.1
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: apple_png
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 0.1.3
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 0.1.3
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: oily_png
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '1.2'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '1.2'
|
69
97
|
description: Extract metadata from iOS packages such as the app name, the app icons
|
70
98
|
or the binary file. This is a diverging fork of github.com/schlu/Ipa-Reader.
|
71
99
|
email: marvinkilling@gmail.com
|
@@ -77,7 +105,6 @@ files:
|
|
77
105
|
- Rakefile
|
78
106
|
- lib/read_ipa.rb
|
79
107
|
- lib/read_ipa/plist_binary.rb
|
80
|
-
- lib/read_ipa/png_file.rb
|
81
108
|
- test/test_read_ipa.rb
|
82
109
|
homepage: https://github.com/playtestcloud/read_ipa
|
83
110
|
licenses:
|
data/lib/read_ipa/png_file.rb
DELETED
@@ -1,113 +0,0 @@
|
|
1
|
-
# direct port of python code at https://gist.github.com/4141831#file_ipin.py
|
2
|
-
require 'zlib'
|
3
|
-
|
4
|
-
module ReadIpa
|
5
|
-
class PngFile
|
6
|
-
attr_accessor :raw_data, :width, :height
|
7
|
-
|
8
|
-
def initialize(oldPNG)
|
9
|
-
# begin
|
10
|
-
self.raw_data = extract_apple_png(oldPNG)
|
11
|
-
# rescue
|
12
|
-
# self.width, self.height = oldPNG[0x10..0x18].unpack('NN')
|
13
|
-
# self.raw_data = oldPNG
|
14
|
-
# end
|
15
|
-
end
|
16
|
-
|
17
|
-
def extract_apple_png(oldPNG)
|
18
|
-
pngheader = "\x89PNG\r\n\x1A\n".b
|
19
|
-
|
20
|
-
if oldPNG[0...8] != pngheader
|
21
|
-
return nil
|
22
|
-
end
|
23
|
-
|
24
|
-
newPNG = oldPNG[0...8]
|
25
|
-
|
26
|
-
chunkPos = newPNG.length
|
27
|
-
|
28
|
-
idatAcc = "".b
|
29
|
-
breakLoop = false
|
30
|
-
|
31
|
-
# For each chunk in the PNG file
|
32
|
-
while chunkPos < oldPNG.length
|
33
|
-
skip = false
|
34
|
-
|
35
|
-
# Reading chunk
|
36
|
-
chunkLength = oldPNG[chunkPos...chunkPos+4]
|
37
|
-
chunkLength = chunkLength.unpack("N")[0]
|
38
|
-
chunkType = oldPNG[chunkPos+4...chunkPos+8]
|
39
|
-
chunkData = oldPNG[chunkPos+8...chunkPos+8+chunkLength]
|
40
|
-
chunkCRC = oldPNG[chunkPos+chunkLength+8...chunkPos+chunkLength+12]
|
41
|
-
chunkCRC = chunkCRC.unpack("N")[0]
|
42
|
-
chunkPos += chunkLength + 12
|
43
|
-
|
44
|
-
# Parsing the header chunk
|
45
|
-
if chunkType == "IHDR".b
|
46
|
-
self.width = chunkData[0...4].unpack("N")[0]
|
47
|
-
self.height = chunkData[4...8].unpack("N")[0]
|
48
|
-
end
|
49
|
-
|
50
|
-
# Parsing the image chunk
|
51
|
-
if chunkType == "IDAT".b
|
52
|
-
# Store the chunk data for later decompression
|
53
|
-
idatAcc += chunkData
|
54
|
-
skip = true
|
55
|
-
end
|
56
|
-
|
57
|
-
# Removing CgBI chunk
|
58
|
-
if chunkType == "CgBI".b
|
59
|
-
skip = true
|
60
|
-
end
|
61
|
-
|
62
|
-
# Stopping the PNG file parsing
|
63
|
-
if chunkType == "IEND".b
|
64
|
-
# Uncompressing the image chunk
|
65
|
-
inf = Zlib::Inflate.new(-Zlib::MAX_WBITS)
|
66
|
-
chunkData = inf.inflate(idatAcc)
|
67
|
-
inf.finish
|
68
|
-
inf.close
|
69
|
-
|
70
|
-
chunkType = "IDAT".b
|
71
|
-
|
72
|
-
# Swapping red & blue bytes for each pixel
|
73
|
-
newdata = "".b
|
74
|
-
|
75
|
-
self.height.times do
|
76
|
-
i = newdata.length
|
77
|
-
newdata += chunkData[i..i].to_s
|
78
|
-
self.width.times do
|
79
|
-
i = newdata.length
|
80
|
-
newdata += chunkData[i+2..i+2].to_s
|
81
|
-
newdata += chunkData[i+1..i+1].to_s
|
82
|
-
newdata += chunkData[i+0..i+0].to_s
|
83
|
-
newdata += chunkData[i+3..i+3].to_s
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
# Compressing the image chunk
|
88
|
-
chunkData = newdata
|
89
|
-
chunkData = Zlib::Deflate.deflate( chunkData )
|
90
|
-
chunkLength = chunkData.length
|
91
|
-
chunkCRC = Zlib.crc32(chunkType)
|
92
|
-
chunkCRC = Zlib.crc32(chunkData, chunkCRC)
|
93
|
-
chunkCRC = (chunkCRC + 0x100000000) % 0x100000000
|
94
|
-
breakLoop = true
|
95
|
-
end
|
96
|
-
|
97
|
-
if !skip
|
98
|
-
newPNG += [chunkLength].pack("N")
|
99
|
-
newPNG += chunkType
|
100
|
-
if chunkLength > 0
|
101
|
-
newPNG += chunkData
|
102
|
-
end
|
103
|
-
newPNG += [chunkCRC].pack("N")
|
104
|
-
end
|
105
|
-
|
106
|
-
break if breakLoop
|
107
|
-
end
|
108
|
-
|
109
|
-
return newPNG
|
110
|
-
end
|
111
|
-
|
112
|
-
end
|
113
|
-
end
|