-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsolve.py
90 lines (63 loc) · 2.03 KB
/
solve.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import zlib
import binascii
from enum import Enum
PNG_MAGIC = b'\x89PNG\r\n\x1a\n'
PNG_IHDR = b'IHDR'
PNG_IDAT = b'IDAT'
PNG_IEND = b'IEND'
class PNGIHDREnum(Enum):
def to_bytes(self):
return self.value.to_bytes(1, 'big')
class PNGColorType(PNGIHDREnum):
GRAYSCALE = 0
TRUECOLOR = 2
INDEXED_COLOR = 3
GRAYSCALE_ALPHA = 4
TRUECOLOR_ALPHA = 6
class PNGFilter(PNGIHDREnum):
NONE = 0
SUB = 1
UP = 2
AVERAGE = 3
PAETH = 4
class PNGInterlace(PNGIHDREnum):
NONE = 0
ADAM7 = 1
class PNGCompression(PNGIHDREnum):
DEFLATE = 0
def create_chunk(chunk_type, data=b''):
return len(data).to_bytes(4, 'big') + chunk_type + data + binascii.crc32(chunk_type + data).to_bytes(4, 'big')
def create_header(
width, height,
bit_depth=8,
color_type=PNGColorType.GRAYSCALE,
compression=PNGCompression.DEFLATE,
filter_method=PNGFilter.NONE,
interlace_method=PNGInterlace.NONE
):
data = width.to_bytes(4, 'big') + height.to_bytes(4, 'big') + \
bit_depth.to_bytes() + color_type.to_bytes() + \
compression.to_bytes() + filter_method.to_bytes() + interlace_method.to_bytes()
return create_chunk(PNG_IHDR, data)
def create_idat_filter_none(width, height, data):
scanline_size = width + 1
scanline = b'\x00' + data[:scanline_size]
filtered_data = bytearray(scanline)
for i in range(scanline_size, len(data), scanline_size):
scanline = data[i:i + scanline_size]
filtered_data.append(0)
filtered_data.extend(scanline)
return bytes(filtered_data)
def create_png(width, height, data):
idat = create_idat_filter_none(width, height, data)
idat = zlib.compress(idat, level=0)
return PNG_MAGIC + \
create_header(width, height) + \
create_chunk(PNG_IDAT, idat) + \
create_chunk(PNG_IEND)
with open("solve0.png", "wb") as f:
im = create_png(1, 1, b'\x00')
f.write(im)
with open("solve255.png", "wb") as f:
im = create_png(1, 1, b'\xff')
f.write(im)