apftool 0.3.2__tar.gz → 0.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- apftool-0.4.0/PKG-INFO +63 -0
- apftool-0.4.0/README.md +52 -0
- apftool-0.4.0/apftool/__init__.py +37 -0
- {apftool-0.3.2 → apftool-0.4.0}/apftool/af2tool.py +4 -2
- {apftool-0.3.2 → apftool-0.4.0}/apftool/apftool.py +2 -1
- apftool-0.4.0/apftool/otabtool.py +92 -0
- apftool-0.4.0/apftool/test.py +85 -0
- {apftool-0.3.2 → apftool-0.4.0}/apftool/wbmptool.py +2 -2
- apftool-0.4.0/apftool.egg-info/PKG-INFO +63 -0
- {apftool-0.3.2 → apftool-0.4.0}/apftool.egg-info/SOURCES.txt +2 -0
- {apftool-0.3.2 → apftool-0.4.0}/pyproject.toml +2 -2
- apftool-0.3.2/PKG-INFO +0 -35
- apftool-0.3.2/README.md +0 -24
- apftool-0.3.2/apftool/__init__.py +0 -6
- apftool-0.3.2/apftool.egg-info/PKG-INFO +0 -35
- {apftool-0.3.2 → apftool-0.4.0}/LICENSE +0 -0
- {apftool-0.3.2 → apftool-0.4.0}/apftool.egg-info/dependency_links.txt +0 -0
- {apftool-0.3.2 → apftool-0.4.0}/apftool.egg-info/entry_points.txt +0 -0
- {apftool-0.3.2 → apftool-0.4.0}/apftool.egg-info/requires.txt +0 -0
- {apftool-0.3.2 → apftool-0.4.0}/apftool.egg-info/top_level.txt +0 -0
- {apftool-0.3.2 → apftool-0.4.0}/setup.cfg +0 -0
apftool-0.4.0/PKG-INFO
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: apftool
|
|
3
|
+
Version: 0.4.0
|
|
4
|
+
Summary: Encoder and decoder for Aperture Science Image Format (apf), Aperture Science Image Format 2 (apf2), Wireless Bitmap (wbmp), and Over-The-Air Bitmap (otb)
|
|
5
|
+
Author: Mari (kbity)
|
|
6
|
+
Requires-Python: >=3.10
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Requires-Dist: Pillow
|
|
10
|
+
Dynamic: license-file
|
|
11
|
+
|
|
12
|
+
# A library for converting to and from Aperture Science apf files, the custom extended apf2s, and otb/wbmp images.
|
|
13
|
+
|
|
14
|
+
## usage:
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
import apftool
|
|
18
|
+
|
|
19
|
+
apfString = apftool.encodeapf(pngObject) # turns image bytes object into apf string
|
|
20
|
+
pngObject = apftool.decodeapf(apfString) # turns apf string object into image bytes
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## funcs and features
|
|
24
|
+
|
|
25
|
+
### encoders:
|
|
26
|
+
|
|
27
|
+
`encodeapf(img: bytes, lineskip: int = 1, findbestlineskip: bool = False)` takes image bytes and outputs apf string. lineskip is interleave value, findbestlineskip brute-forces different interleave values to the possible max of 199 and uses the smallest one.
|
|
28
|
+
|
|
29
|
+
`encodeaf2(img: bytes, lineskip: int = 1, findbestlineskip: bool = False, legacy: bool = False, trans: bool = False, pal: int = 95)` takes image bytes and outputs af2 string. lineskip is interleave value, findbestlineskip brute-forces different interleave values to the provided lineskip and uses the smallest one. legacy uses apf1-style 1 color data instead of a 95 color palette. trans enables/disables transparency, which overrides a color. pal allows you to manually force a smaller palette.
|
|
30
|
+
|
|
31
|
+
`encodewbmp(img: Image)` takes pil image object and outputs wbmp bytes
|
|
32
|
+
|
|
33
|
+
`encodeotab(img: Image, width=255, height=255)` takes pil image object and outputs otb bytes. max size is 255x255
|
|
34
|
+
|
|
35
|
+
### decoders:
|
|
36
|
+
|
|
37
|
+
`decodeany(data, format: str = 'PNG', returnImageObject: bool = False)` takes in string or bytes and outputs bytes image or PIL image using best-guess for the decoders
|
|
38
|
+
|
|
39
|
+
`decodeapf(apf: str, format: str = 'PNG', returnImageObject: bool = False)` takes apf string and outputs either image bytes in specified format or pil image object
|
|
40
|
+
|
|
41
|
+
`decodeaf2(af2: str, format: str = 'PNG', returnImageObject: bool = False)` hi i am the same thing, i am literally a dropin replacement for decodeapf too
|
|
42
|
+
|
|
43
|
+
`decodewbmp(wbmp: bytes, format: str = 'PNG', returnImageObject: bool = False)` takes wbmp bytes and outputs either image bytes in specified format or pil image object
|
|
44
|
+
|
|
45
|
+
`decodeotab(otab: bytes, format: str = 'PNG', returnImageObject: bool = False)` hi i have the same usage as decodewbmp but for .otb images
|
|
46
|
+
|
|
47
|
+
## dependancies
|
|
48
|
+
|
|
49
|
+
`PIL, io, textwrap, math` (apftool)
|
|
50
|
+
|
|
51
|
+
most of these a builtins but you may need to install PIL seperately
|
|
52
|
+
|
|
53
|
+
## changelog:
|
|
54
|
+
|
|
55
|
+
0.4.0 - add support for otb images, improve readme.md, and add decodeany to decode all suported formats automatically
|
|
56
|
+
|
|
57
|
+
0.3.3 - make the af2 decoder more lenient
|
|
58
|
+
|
|
59
|
+
0.3.2 - i forgot but i think it made the af2 decoder more lenient
|
|
60
|
+
|
|
61
|
+
0.3.1 - fix 0.3.0
|
|
62
|
+
|
|
63
|
+
0.3.0 - add support for wbmp images, broken release
|
apftool-0.4.0/README.md
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# A library for converting to and from Aperture Science apf files, the custom extended apf2s, and otb/wbmp images.
|
|
2
|
+
|
|
3
|
+
## usage:
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
import apftool
|
|
7
|
+
|
|
8
|
+
apfString = apftool.encodeapf(pngObject) # turns image bytes object into apf string
|
|
9
|
+
pngObject = apftool.decodeapf(apfString) # turns apf string object into image bytes
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## funcs and features
|
|
13
|
+
|
|
14
|
+
### encoders:
|
|
15
|
+
|
|
16
|
+
`encodeapf(img: bytes, lineskip: int = 1, findbestlineskip: bool = False)` takes image bytes and outputs apf string. lineskip is interleave value, findbestlineskip brute-forces different interleave values to the possible max of 199 and uses the smallest one.
|
|
17
|
+
|
|
18
|
+
`encodeaf2(img: bytes, lineskip: int = 1, findbestlineskip: bool = False, legacy: bool = False, trans: bool = False, pal: int = 95)` takes image bytes and outputs af2 string. lineskip is interleave value, findbestlineskip brute-forces different interleave values to the provided lineskip and uses the smallest one. legacy uses apf1-style 1 color data instead of a 95 color palette. trans enables/disables transparency, which overrides a color. pal allows you to manually force a smaller palette.
|
|
19
|
+
|
|
20
|
+
`encodewbmp(img: Image)` takes pil image object and outputs wbmp bytes
|
|
21
|
+
|
|
22
|
+
`encodeotab(img: Image, width=255, height=255)` takes pil image object and outputs otb bytes. max size is 255x255
|
|
23
|
+
|
|
24
|
+
### decoders:
|
|
25
|
+
|
|
26
|
+
`decodeany(data, format: str = 'PNG', returnImageObject: bool = False)` takes in string or bytes and outputs bytes image or PIL image using best-guess for the decoders
|
|
27
|
+
|
|
28
|
+
`decodeapf(apf: str, format: str = 'PNG', returnImageObject: bool = False)` takes apf string and outputs either image bytes in specified format or pil image object
|
|
29
|
+
|
|
30
|
+
`decodeaf2(af2: str, format: str = 'PNG', returnImageObject: bool = False)` hi i am the same thing, i am literally a dropin replacement for decodeapf too
|
|
31
|
+
|
|
32
|
+
`decodewbmp(wbmp: bytes, format: str = 'PNG', returnImageObject: bool = False)` takes wbmp bytes and outputs either image bytes in specified format or pil image object
|
|
33
|
+
|
|
34
|
+
`decodeotab(otab: bytes, format: str = 'PNG', returnImageObject: bool = False)` hi i have the same usage as decodewbmp but for .otb images
|
|
35
|
+
|
|
36
|
+
## dependancies
|
|
37
|
+
|
|
38
|
+
`PIL, io, textwrap, math` (apftool)
|
|
39
|
+
|
|
40
|
+
most of these a builtins but you may need to install PIL seperately
|
|
41
|
+
|
|
42
|
+
## changelog:
|
|
43
|
+
|
|
44
|
+
0.4.0 - add support for otb images, improve readme.md, and add decodeany to decode all suported formats automatically
|
|
45
|
+
|
|
46
|
+
0.3.3 - make the af2 decoder more lenient
|
|
47
|
+
|
|
48
|
+
0.3.2 - i forgot but i think it made the af2 decoder more lenient
|
|
49
|
+
|
|
50
|
+
0.3.1 - fix 0.3.0
|
|
51
|
+
|
|
52
|
+
0.3.0 - add support for wbmp images, broken release
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# apftool/__init__.py
|
|
2
|
+
|
|
3
|
+
from .apftool import encodeapf, decodeapf
|
|
4
|
+
from .af2tool import encodeaf2, decodeaf2
|
|
5
|
+
from .wbmptool import encodewbmp, decodewbmp
|
|
6
|
+
from .otabtool import encodeotab, decodeotab
|
|
7
|
+
|
|
8
|
+
extensions = (".apf", ".apf2", ".aif", ".af2", ".ap2", ".aif2", ".txt", ".text")
|
|
9
|
+
extensions_apf = (".apf", ".aif", ".txt", ".text")
|
|
10
|
+
extensions_apf2 = (".apf2", ".af2", ".ap2", ".aif2", ".txt")
|
|
11
|
+
extensions_wbmp = (".wbmp", ".wbitmap", ".wbm")
|
|
12
|
+
extensions_otab = (".otb", ".ota", ".otab")
|
|
13
|
+
|
|
14
|
+
extensions_txt = (".txt", ".text") # txt is seen as a generic container for apf/apf2 because they're just txt files
|
|
15
|
+
extensions_all = (".apf", ".apf2", ".aif", ".af2", ".ap2", ".aif2", ".txt", ".text", ".wbmp", ".wbitmap", ".wbm", ".otb", ".ota", ".otab") # useful for decodeany
|
|
16
|
+
|
|
17
|
+
def decodeany(data, format: str = 'PNG', returnImageObject: bool = False):
|
|
18
|
+
|
|
19
|
+
if isinstance(data, str):
|
|
20
|
+
return decodeaf2(data, format, returnImageObject) # apf and af2 decoder
|
|
21
|
+
|
|
22
|
+
elif isinstance(data, bytes):
|
|
23
|
+
if data.startswith(b'\x00\x00'): # type 00 wbmp header
|
|
24
|
+
return decodewbmp(data, format, returnImageObject)
|
|
25
|
+
|
|
26
|
+
elif data.startswith(b'APERTURE IMAGE FORMAT (c) '): # this makes me GLaD
|
|
27
|
+
apfX = data.decode("ascii")
|
|
28
|
+
return decodeaf2(apfX, format, returnImageObject) # yeah ok vrumbler
|
|
29
|
+
|
|
30
|
+
elif data.startswith(b'\x00'): # looser check that otbs follow
|
|
31
|
+
return decodeotab(data, format, returnImageObject) # assume otb if it doesnt look like a wbmp
|
|
32
|
+
|
|
33
|
+
else:
|
|
34
|
+
raise Exception("This is definitely not an otb or wbmp")
|
|
35
|
+
|
|
36
|
+
else:
|
|
37
|
+
raise Exception("Invalid data! Must be bytes or str")
|
|
@@ -13,7 +13,8 @@ def af2_apfdecodedata(data: str, h: int, w: int, apfbuffer: list, lineskip: int,
|
|
|
13
13
|
for char in data:
|
|
14
14
|
runlen = ord(char) - 32
|
|
15
15
|
for i in range(runlen):
|
|
16
|
-
apfbuffer
|
|
16
|
+
if 0 <= y < len(apfbuffer) and 0 <= x < len(apfbuffer[0]):
|
|
17
|
+
apfbuffer[y][x] = (state)
|
|
17
18
|
x += 1
|
|
18
19
|
if not x < w:
|
|
19
20
|
y = y - lineskip
|
|
@@ -61,7 +62,8 @@ def af2decodedata(data: str, h: int, w: int, apfbuffer: list, lineskip: int, pal
|
|
|
61
62
|
runlen = ord(data[pair*2+1]) - 32
|
|
62
63
|
|
|
63
64
|
for i in range(runlen):
|
|
64
|
-
apfbuffer
|
|
65
|
+
if 0 <= y < len(apfbuffer) and 0 <= x < len(apfbuffer[0]):
|
|
66
|
+
apfbuffer[y][x] = pal[color]
|
|
65
67
|
|
|
66
68
|
x += 1
|
|
67
69
|
if x >= w:
|
|
@@ -31,7 +31,8 @@ def decodeapf(apf: str, format: str = 'PNG', returnImageObject: bool = False):
|
|
|
31
31
|
for char in data:
|
|
32
32
|
runlen = ord(char) - 32
|
|
33
33
|
for i in range(runlen):
|
|
34
|
-
apfbuffer
|
|
34
|
+
if 0 <= y < len(apfbuffer) and 0 <= x < len(apfbuffer[0]):
|
|
35
|
+
apfbuffer[y][x] = (state)
|
|
35
36
|
x += 1
|
|
36
37
|
if not x < w:
|
|
37
38
|
y = y - lineskip
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import io, textwrap, os, math
|
|
2
|
+
from PIL import Image, ImageSequence, ImageOps
|
|
3
|
+
|
|
4
|
+
def bitstring_to_bytes(s):
|
|
5
|
+
s = s.replace(" ", "")
|
|
6
|
+
s = s.replace(",", "")
|
|
7
|
+
s = s.replace("_", "")
|
|
8
|
+
return int(s, 2).to_bytes((len(s) + 7) // 8, byteorder='big')
|
|
9
|
+
|
|
10
|
+
def encodeotab(img: Image, width=255, height=255):
|
|
11
|
+
if width > 255 or height > 255:
|
|
12
|
+
raise Exception("Invalid Resolution")
|
|
13
|
+
img = img.convert("1")
|
|
14
|
+
res = img.size
|
|
15
|
+
|
|
16
|
+
# don't upscale
|
|
17
|
+
if width > res[0]:
|
|
18
|
+
width = res[0]
|
|
19
|
+
if height > res[1]:
|
|
20
|
+
height = res[1]
|
|
21
|
+
img = img.resize((width, height))
|
|
22
|
+
|
|
23
|
+
pixels = img.load()
|
|
24
|
+
payload = b'\x00' # type 0 hardcoded header
|
|
25
|
+
payload += width.to_bytes(1, 'big')
|
|
26
|
+
payload += height.to_bytes(1, 'big')
|
|
27
|
+
payload += b'\x01' # 1 color hardcoded header
|
|
28
|
+
print(f"header: {payload.hex()}")
|
|
29
|
+
bitmap = [[pixels[x, y] for x in range(img.width)] for y in range(img.height)]
|
|
30
|
+
|
|
31
|
+
collection = ""
|
|
32
|
+
cat = 0
|
|
33
|
+
for hline in bitmap:
|
|
34
|
+
for px in hline:
|
|
35
|
+
cat += 1
|
|
36
|
+
if px:
|
|
37
|
+
collection += "0"
|
|
38
|
+
else:
|
|
39
|
+
collection += "1"
|
|
40
|
+
if len(collection) == 8:
|
|
41
|
+
payload += bitstring_to_bytes(collection)
|
|
42
|
+
collection = ""
|
|
43
|
+
if cat == width:
|
|
44
|
+
if collection:
|
|
45
|
+
payload += bitstring_to_bytes(collection)
|
|
46
|
+
collection = ""
|
|
47
|
+
cat = 0
|
|
48
|
+
|
|
49
|
+
return payload
|
|
50
|
+
|
|
51
|
+
def decodeotab(otab: bytes, format: str = 'PNG', returnImageObject: bool = False):
|
|
52
|
+
w = 0
|
|
53
|
+
h = 0
|
|
54
|
+
it = 0
|
|
55
|
+
|
|
56
|
+
headeryeah = False
|
|
57
|
+
img = None
|
|
58
|
+
for byte in otab:
|
|
59
|
+
if headeryeah:
|
|
60
|
+
for p in range(0, 8):
|
|
61
|
+
bit = (byte >> (7 - p)) & 1
|
|
62
|
+
x = it % w
|
|
63
|
+
y = it // w
|
|
64
|
+
if 0 <= x < w and 0 <= y < h:
|
|
65
|
+
pixels[x, y] = not bit
|
|
66
|
+
it += 1
|
|
67
|
+
else:
|
|
68
|
+
it += 1
|
|
69
|
+
if it == 1:
|
|
70
|
+
if not byte == 0:
|
|
71
|
+
raise Exception("Invalid or unsupported Otb!")
|
|
72
|
+
elif w == 0:
|
|
73
|
+
w = byte
|
|
74
|
+
elif h == 0:
|
|
75
|
+
h = byte
|
|
76
|
+
img = Image.new("1", (w, h))
|
|
77
|
+
pixels = img.load()
|
|
78
|
+
elif it == 4:
|
|
79
|
+
if byte != 1:
|
|
80
|
+
raise Exception("Invalid or unsupported Otb!")
|
|
81
|
+
else:
|
|
82
|
+
headeryeah = True
|
|
83
|
+
it = 0
|
|
84
|
+
|
|
85
|
+
if returnImageObject:
|
|
86
|
+
return img
|
|
87
|
+
else:
|
|
88
|
+
imageData = io.BytesIO()
|
|
89
|
+
img.save(imageData, format=format)
|
|
90
|
+
imageData = imageData.getvalue()
|
|
91
|
+
return imageData
|
|
92
|
+
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
from otabtool import encodeotab
|
|
2
|
+
import io
|
|
3
|
+
from PIL import Image
|
|
4
|
+
|
|
5
|
+
# apf
|
|
6
|
+
# the following is an example of usage of the decoder. it expects a string as an input, outputs a bytes image.
|
|
7
|
+
#file_path = 'input.apf'
|
|
8
|
+
#with open(file_path, 'r') as f:
|
|
9
|
+
# file_content = f.read()
|
|
10
|
+
#decodedapf = decodeapf(file_content)
|
|
11
|
+
#with open("output.png", "wb") as f:
|
|
12
|
+
# f.write(decodedapf)
|
|
13
|
+
|
|
14
|
+
# the following is an example of usage of the encoder. it expects a bytes image as an input, outputs a string.
|
|
15
|
+
#file_path = 'output.png'
|
|
16
|
+
#with open(file_path, "rb") as f:
|
|
17
|
+
# data = io.BytesIO()
|
|
18
|
+
# data = f.read()
|
|
19
|
+
|
|
20
|
+
#encodedapf = encodeapf(data, 3, True)
|
|
21
|
+
#with open("output.apf", "w") as f:
|
|
22
|
+
# f.write(encodedapf)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
# af2
|
|
27
|
+
# the following is an example of usage of the decoder. it expects a string as an input, outputs a bytes image.
|
|
28
|
+
#file_path = 'input.af2'
|
|
29
|
+
#with open(file_path, 'r') as f:
|
|
30
|
+
# file_content = f.read()
|
|
31
|
+
#decodedapf = decodeaf2(file_content, 'PNG')
|
|
32
|
+
#with open("output.png", "wb") as f:
|
|
33
|
+
# f.write(decodedapf)
|
|
34
|
+
|
|
35
|
+
# the following is an example of usage of the encoder. it expects a bytes image as an input, outputs a string.
|
|
36
|
+
#file_path = 'input.png'
|
|
37
|
+
#with open(file_path, "rb") as f:
|
|
38
|
+
# data = io.BytesIO()
|
|
39
|
+
# data = f.read()
|
|
40
|
+
|
|
41
|
+
#encodedapf = encodeaf2(data, 9, False, False, True)
|
|
42
|
+
#with open("output.af2", "w") as f:
|
|
43
|
+
# f.write(encodedapf)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
# wbmp
|
|
48
|
+
# the following is an example of usage of the decoder. it expects a string as an input, outputs a bytes image.
|
|
49
|
+
#file_path = 'input.wbmp'
|
|
50
|
+
#with open(file_path, 'rb') as f:
|
|
51
|
+
# file_content = f.read()
|
|
52
|
+
#decodedwbmp = decodewbmp(file_content)
|
|
53
|
+
#with open("output.png", "wb") as f:
|
|
54
|
+
# f.write(decodedwbmp)
|
|
55
|
+
|
|
56
|
+
# the following is an example of usage of the encoder. it expects a bytes image as an input, outputs a string.
|
|
57
|
+
#file_path = 'output.png'
|
|
58
|
+
#with open(file_path, "rb") as f:
|
|
59
|
+
# data = io.BytesIO()
|
|
60
|
+
# data = f.read()
|
|
61
|
+
|
|
62
|
+
#encodedwbmp = encodewbmp(data)
|
|
63
|
+
#with open("output.wbmp", "w") as f:
|
|
64
|
+
# f.write(encodedwbmp)
|
|
65
|
+
|
|
66
|
+
# otab
|
|
67
|
+
# the following is an example of usage of the decoder. it expects a string as an input, outputs a bytes image.
|
|
68
|
+
#file_path = 'input.otb'
|
|
69
|
+
#with open(file_path, 'rb') as f:
|
|
70
|
+
# file_content = f.read()
|
|
71
|
+
#decodedotab = decodeotab(file_content)
|
|
72
|
+
#with open("output.png", "wb") as f:
|
|
73
|
+
# f.write(decodedotab)
|
|
74
|
+
|
|
75
|
+
# the following is an example of usage of the encoder. it expects a bytes image as an input, outputs a string.
|
|
76
|
+
#file_path = 'biohazzard1bbp.png'
|
|
77
|
+
#with open(file_path, "rb") as f:
|
|
78
|
+
# data = io.BytesIO()
|
|
79
|
+
# data = f.read()
|
|
80
|
+
#
|
|
81
|
+
#image = Image.open(io.BytesIO(data))
|
|
82
|
+
#encodedotab = encodeotab(image)
|
|
83
|
+
#with open("output.otb", "wb") as f:
|
|
84
|
+
# f.write(encodedotab)
|
|
85
|
+
|
|
@@ -42,7 +42,7 @@ def encodewbmp(img: Image):
|
|
|
42
42
|
height = res[1]
|
|
43
43
|
payload += mk_uintvar(width)
|
|
44
44
|
payload += mk_uintvar(height)
|
|
45
|
-
print(f"header: {payload.hex()}")
|
|
45
|
+
#print(f"header: {payload.hex()}")
|
|
46
46
|
bitmap = [[pixels[x, y] for x in range(img.width)] for y in range(img.height)]
|
|
47
47
|
|
|
48
48
|
collection = ""
|
|
@@ -113,7 +113,7 @@ def decodewbmp(wbmp: bytes, format: str = 'PNG', returnImageObject: bool = False
|
|
|
113
113
|
pixels = img.load()
|
|
114
114
|
it = 0
|
|
115
115
|
ds = w-oldw
|
|
116
|
-
print(ds)
|
|
116
|
+
#print(ds)
|
|
117
117
|
img = img.crop((0,0,oldw,h))
|
|
118
118
|
|
|
119
119
|
if returnImageObject:
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: apftool
|
|
3
|
+
Version: 0.4.0
|
|
4
|
+
Summary: Encoder and decoder for Aperture Science Image Format (apf), Aperture Science Image Format 2 (apf2), Wireless Bitmap (wbmp), and Over-The-Air Bitmap (otb)
|
|
5
|
+
Author: Mari (kbity)
|
|
6
|
+
Requires-Python: >=3.10
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Requires-Dist: Pillow
|
|
10
|
+
Dynamic: license-file
|
|
11
|
+
|
|
12
|
+
# A library for converting to and from Aperture Science apf files, the custom extended apf2s, and otb/wbmp images.
|
|
13
|
+
|
|
14
|
+
## usage:
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
import apftool
|
|
18
|
+
|
|
19
|
+
apfString = apftool.encodeapf(pngObject) # turns image bytes object into apf string
|
|
20
|
+
pngObject = apftool.decodeapf(apfString) # turns apf string object into image bytes
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## funcs and features
|
|
24
|
+
|
|
25
|
+
### encoders:
|
|
26
|
+
|
|
27
|
+
`encodeapf(img: bytes, lineskip: int = 1, findbestlineskip: bool = False)` takes image bytes and outputs apf string. lineskip is interleave value, findbestlineskip brute-forces different interleave values to the possible max of 199 and uses the smallest one.
|
|
28
|
+
|
|
29
|
+
`encodeaf2(img: bytes, lineskip: int = 1, findbestlineskip: bool = False, legacy: bool = False, trans: bool = False, pal: int = 95)` takes image bytes and outputs af2 string. lineskip is interleave value, findbestlineskip brute-forces different interleave values to the provided lineskip and uses the smallest one. legacy uses apf1-style 1 color data instead of a 95 color palette. trans enables/disables transparency, which overrides a color. pal allows you to manually force a smaller palette.
|
|
30
|
+
|
|
31
|
+
`encodewbmp(img: Image)` takes pil image object and outputs wbmp bytes
|
|
32
|
+
|
|
33
|
+
`encodeotab(img: Image, width=255, height=255)` takes pil image object and outputs otb bytes. max size is 255x255
|
|
34
|
+
|
|
35
|
+
### decoders:
|
|
36
|
+
|
|
37
|
+
`decodeany(data, format: str = 'PNG', returnImageObject: bool = False)` takes in string or bytes and outputs bytes image or PIL image using best-guess for the decoders
|
|
38
|
+
|
|
39
|
+
`decodeapf(apf: str, format: str = 'PNG', returnImageObject: bool = False)` takes apf string and outputs either image bytes in specified format or pil image object
|
|
40
|
+
|
|
41
|
+
`decodeaf2(af2: str, format: str = 'PNG', returnImageObject: bool = False)` hi i am the same thing, i am literally a dropin replacement for decodeapf too
|
|
42
|
+
|
|
43
|
+
`decodewbmp(wbmp: bytes, format: str = 'PNG', returnImageObject: bool = False)` takes wbmp bytes and outputs either image bytes in specified format or pil image object
|
|
44
|
+
|
|
45
|
+
`decodeotab(otab: bytes, format: str = 'PNG', returnImageObject: bool = False)` hi i have the same usage as decodewbmp but for .otb images
|
|
46
|
+
|
|
47
|
+
## dependancies
|
|
48
|
+
|
|
49
|
+
`PIL, io, textwrap, math` (apftool)
|
|
50
|
+
|
|
51
|
+
most of these a builtins but you may need to install PIL seperately
|
|
52
|
+
|
|
53
|
+
## changelog:
|
|
54
|
+
|
|
55
|
+
0.4.0 - add support for otb images, improve readme.md, and add decodeany to decode all suported formats automatically
|
|
56
|
+
|
|
57
|
+
0.3.3 - make the af2 decoder more lenient
|
|
58
|
+
|
|
59
|
+
0.3.2 - i forgot but i think it made the af2 decoder more lenient
|
|
60
|
+
|
|
61
|
+
0.3.1 - fix 0.3.0
|
|
62
|
+
|
|
63
|
+
0.3.0 - add support for wbmp images, broken release
|
|
@@ -4,8 +4,8 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "apftool"
|
|
7
|
-
version = "0.
|
|
8
|
-
description = "Aperture Science Image Format (apf)
|
|
7
|
+
version = "0.4.0"
|
|
8
|
+
description = "Encoder and decoder for Aperture Science Image Format (apf), Aperture Science Image Format 2 (apf2), Wireless Bitmap (wbmp), and Over-The-Air Bitmap (otb)"
|
|
9
9
|
authors = [{name = "Mari (kbity)"}]
|
|
10
10
|
readme = "README.md"
|
|
11
11
|
requires-python = ">=3.10"
|
apftool-0.3.2/PKG-INFO
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: apftool
|
|
3
|
-
Version: 0.3.2
|
|
4
|
-
Summary: Aperture Science Image Format (apf) encoder and decoder
|
|
5
|
-
Author: Mari (kbity)
|
|
6
|
-
Requires-Python: >=3.10
|
|
7
|
-
Description-Content-Type: text/markdown
|
|
8
|
-
License-File: LICENSE
|
|
9
|
-
Requires-Dist: Pillow
|
|
10
|
-
Dynamic: license-file
|
|
11
|
-
|
|
12
|
-
A library for converting to and from Aperture Science apf files, the custom extended apf2s, and wbmp images.
|
|
13
|
-
|
|
14
|
-
usage:
|
|
15
|
-
|
|
16
|
-
```
|
|
17
|
-
import apftool
|
|
18
|
-
apfString = apftool.encodeapf(pngObject) # turns image bytes object into apf string
|
|
19
|
-
pngObject = apftool.decodeapf(apfString) # turns apf string object into image bytes
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
included is a simple cli tool.
|
|
23
|
-
|
|
24
|
-
usage:
|
|
25
|
-
|
|
26
|
-
```
|
|
27
|
-
python apfcli.py maricom.png # creates maricom.apf
|
|
28
|
-
python apfcli.py maricom.apf # creates maricom.png
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
dependancies: `PIL, io` (apftool)
|
|
32
|
-
|
|
33
|
-
dependancies: `sys, os, io` (apfcli)
|
|
34
|
-
|
|
35
|
-
most of these a builtins but you may need to install PIL seporately
|
apftool-0.3.2/README.md
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
A library for converting to and from Aperture Science apf files, the custom extended apf2s, and wbmp images.
|
|
2
|
-
|
|
3
|
-
usage:
|
|
4
|
-
|
|
5
|
-
```
|
|
6
|
-
import apftool
|
|
7
|
-
apfString = apftool.encodeapf(pngObject) # turns image bytes object into apf string
|
|
8
|
-
pngObject = apftool.decodeapf(apfString) # turns apf string object into image bytes
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
included is a simple cli tool.
|
|
12
|
-
|
|
13
|
-
usage:
|
|
14
|
-
|
|
15
|
-
```
|
|
16
|
-
python apfcli.py maricom.png # creates maricom.apf
|
|
17
|
-
python apfcli.py maricom.apf # creates maricom.png
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
dependancies: `PIL, io` (apftool)
|
|
21
|
-
|
|
22
|
-
dependancies: `sys, os, io` (apfcli)
|
|
23
|
-
|
|
24
|
-
most of these a builtins but you may need to install PIL seporately
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
# apftool/__init__.py
|
|
2
|
-
from .apftool import encodeapf, decodeapf
|
|
3
|
-
from .af2tool import encodeaf2, decodeaf2
|
|
4
|
-
from .wbmptool import encodewbmp, decodewbmp
|
|
5
|
-
extensions = (".apf", ".apf2", ".aif", ".af2", ".ap2", ".aif2", ".txt")
|
|
6
|
-
extensions_wbmp = (".wbmp", ".wbitmap", ".wbm")
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: apftool
|
|
3
|
-
Version: 0.3.2
|
|
4
|
-
Summary: Aperture Science Image Format (apf) encoder and decoder
|
|
5
|
-
Author: Mari (kbity)
|
|
6
|
-
Requires-Python: >=3.10
|
|
7
|
-
Description-Content-Type: text/markdown
|
|
8
|
-
License-File: LICENSE
|
|
9
|
-
Requires-Dist: Pillow
|
|
10
|
-
Dynamic: license-file
|
|
11
|
-
|
|
12
|
-
A library for converting to and from Aperture Science apf files, the custom extended apf2s, and wbmp images.
|
|
13
|
-
|
|
14
|
-
usage:
|
|
15
|
-
|
|
16
|
-
```
|
|
17
|
-
import apftool
|
|
18
|
-
apfString = apftool.encodeapf(pngObject) # turns image bytes object into apf string
|
|
19
|
-
pngObject = apftool.decodeapf(apfString) # turns apf string object into image bytes
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
included is a simple cli tool.
|
|
23
|
-
|
|
24
|
-
usage:
|
|
25
|
-
|
|
26
|
-
```
|
|
27
|
-
python apfcli.py maricom.png # creates maricom.apf
|
|
28
|
-
python apfcli.py maricom.apf # creates maricom.png
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
dependancies: `PIL, io` (apftool)
|
|
32
|
-
|
|
33
|
-
dependancies: `sys, os, io` (apfcli)
|
|
34
|
-
|
|
35
|
-
most of these a builtins but you may need to install PIL seporately
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|