Skip to content

Commit b58447e

Browse files
author
Sigrid Tofte Thiis
committed
making bgi out of prediction causes less drift
1 parent 3dd2257 commit b58447e

8,056 files changed

Lines changed: 1386744 additions & 215309 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.venv/Lib/site-packages/numpy-2.2.6.dist-info/INSTALLER renamed to .venv/Lib/site-packages/Farama_Notifications-0.0.4.dist-info/INSTALLER

File renamed without changes.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2023 Farama Foundation
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
Metadata-Version: 2.1
2+
Name: Farama-Notifications
3+
Version: 0.0.4
4+
Summary: Notifications for all Farama Foundation maintained libraries.
5+
Home-page: https://github.com/Farama-Foundation/Farama-Notifications
6+
Author: Jordan Terry
7+
Author-email: Jkterry@farama.org
8+
Classifier: Programming Language :: Python :: 3
9+
Classifier: License :: OSI Approved :: MIT License
10+
Classifier: Operating System :: OS Independent
11+
Description-Content-Type: text/markdown
12+
License-File: LICENSE
13+
14+
# Farama-Notifications
15+
Allows for providing notifications on import to all Farama Packages
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
Farama_Notifications-0.0.4.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
2+
Farama_Notifications-0.0.4.dist-info/LICENSE,sha256=f_YzazOuTBaAhuiZoRt8kdNptnWM7iD5Rp1WPwBPies,1074
3+
Farama_Notifications-0.0.4.dist-info/METADATA,sha256=uwf9zjHzwOu3Fql87GY9LXscORikFf9RICmbNUpbq-k,558
4+
Farama_Notifications-0.0.4.dist-info/RECORD,,
5+
Farama_Notifications-0.0.4.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92
6+
Farama_Notifications-0.0.4.dist-info/top_level.txt,sha256=isdjlUtSAEJbdH41jw_aP9MD1hhORQVTtGlXC0WT74E,21
7+
farama_notifications/__init__.py,sha256=Co-TZP7j3M7em1IroSz3Yj7l-hfXDyRTyp8qsEvMDXs,368
8+
farama_notifications/__pycache__/__init__.cpython-310.pyc,,

.venv/Lib/site-packages/setuptools/_vendor/autocommand-2.2.2.dist-info/WHEEL renamed to .venv/Lib/site-packages/Farama_Notifications-0.0.4.dist-info/WHEEL

File renamed without changes.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
farama_notifications
Lines changed: 293 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,293 @@
1+
from __future__ import annotations
2+
3+
import os
4+
from io import BytesIO
5+
from typing import IO
6+
7+
from . import ExifTags, Image, ImageFile
8+
9+
try:
10+
from . import _avif
11+
12+
SUPPORTED = True
13+
except ImportError:
14+
SUPPORTED = False
15+
16+
# Decoder options as module globals, until there is a way to pass parameters
17+
# to Image.open (see https://github.com/python-pillow/Pillow/issues/569)
18+
DECODE_CODEC_CHOICE = "auto"
19+
DEFAULT_MAX_THREADS = 0
20+
21+
22+
def get_codec_version(codec_name: str) -> str | None:
23+
versions = _avif.codec_versions()
24+
for version in versions.split(", "):
25+
if version.split(" [")[0] == codec_name:
26+
return version.split(":")[-1].split(" ")[0]
27+
return None
28+
29+
30+
def _accept(prefix: bytes) -> bool | str:
31+
if prefix[4:8] != b"ftyp":
32+
return False
33+
major_brand = prefix[8:12]
34+
if major_brand in (
35+
# coding brands
36+
b"avif",
37+
b"avis",
38+
# We accept files with AVIF container brands; we can't yet know if
39+
# the ftyp box has the correct compatible brands, but if it doesn't
40+
# then the plugin will raise a SyntaxError which Pillow will catch
41+
# before moving on to the next plugin that accepts the file.
42+
#
43+
# Also, because this file might not actually be an AVIF file, we
44+
# don't raise an error if AVIF support isn't properly compiled.
45+
b"mif1",
46+
b"msf1",
47+
):
48+
if not SUPPORTED:
49+
return (
50+
"image file could not be identified because AVIF support not installed"
51+
)
52+
return True
53+
return False
54+
55+
56+
def _get_default_max_threads() -> int:
57+
if DEFAULT_MAX_THREADS:
58+
return DEFAULT_MAX_THREADS
59+
if hasattr(os, "sched_getaffinity"):
60+
return len(os.sched_getaffinity(0))
61+
else:
62+
return os.cpu_count() or 1
63+
64+
65+
class AvifImageFile(ImageFile.ImageFile):
66+
format = "AVIF"
67+
format_description = "AVIF image"
68+
__frame = -1
69+
70+
def _open(self) -> None:
71+
if not SUPPORTED:
72+
msg = "image file could not be opened because AVIF support not installed"
73+
raise SyntaxError(msg)
74+
75+
if DECODE_CODEC_CHOICE != "auto" and not _avif.decoder_codec_available(
76+
DECODE_CODEC_CHOICE
77+
):
78+
msg = "Invalid opening codec"
79+
raise ValueError(msg)
80+
81+
assert self.fp is not None
82+
self._decoder = _avif.AvifDecoder(
83+
self.fp.read(),
84+
DECODE_CODEC_CHOICE,
85+
_get_default_max_threads(),
86+
)
87+
88+
# Get info from decoder
89+
self._size, self.n_frames, self._mode, icc, exif, exif_orientation, xmp = (
90+
self._decoder.get_info()
91+
)
92+
self.is_animated = self.n_frames > 1
93+
94+
if icc:
95+
self.info["icc_profile"] = icc
96+
if xmp:
97+
self.info["xmp"] = xmp
98+
99+
if exif_orientation != 1 or exif:
100+
exif_data = Image.Exif()
101+
if exif:
102+
exif_data.load(exif)
103+
original_orientation = exif_data.get(ExifTags.Base.Orientation, 1)
104+
else:
105+
original_orientation = 1
106+
if exif_orientation != original_orientation:
107+
exif_data[ExifTags.Base.Orientation] = exif_orientation
108+
exif = exif_data.tobytes()
109+
if exif:
110+
self.info["exif"] = exif
111+
self.seek(0)
112+
113+
def seek(self, frame: int) -> None:
114+
if not self._seek_check(frame):
115+
return
116+
117+
# Set tile
118+
self.__frame = frame
119+
self.tile = [ImageFile._Tile("raw", (0, 0) + self.size, 0, self.mode)]
120+
121+
def load(self) -> Image.core.PixelAccess | None:
122+
if self.tile:
123+
# We need to load the image data for this frame
124+
data, timescale, pts_in_timescales, duration_in_timescales = (
125+
self._decoder.get_frame(self.__frame)
126+
)
127+
self.info["timestamp"] = round(1000 * (pts_in_timescales / timescale))
128+
self.info["duration"] = round(1000 * (duration_in_timescales / timescale))
129+
130+
if self.fp and self._exclusive_fp:
131+
self.fp.close()
132+
self.fp = BytesIO(data)
133+
134+
return super().load()
135+
136+
def load_seek(self, pos: int) -> None:
137+
pass
138+
139+
def tell(self) -> int:
140+
return self.__frame
141+
142+
143+
def _save_all(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None:
144+
_save(im, fp, filename, save_all=True)
145+
146+
147+
def _save(
148+
im: Image.Image, fp: IO[bytes], filename: str | bytes, save_all: bool = False
149+
) -> None:
150+
info = im.encoderinfo.copy()
151+
if save_all:
152+
append_images = list(info.get("append_images", []))
153+
else:
154+
append_images = []
155+
156+
total = 0
157+
for ims in [im] + append_images:
158+
total += getattr(ims, "n_frames", 1)
159+
160+
quality = info.get("quality", 75)
161+
if not isinstance(quality, int) or quality < 0 or quality > 100:
162+
msg = "Invalid quality setting"
163+
raise ValueError(msg)
164+
165+
duration = info.get("duration", 0)
166+
subsampling = info.get("subsampling", "4:2:0")
167+
speed = info.get("speed", 6)
168+
max_threads = info.get("max_threads", _get_default_max_threads())
169+
codec = info.get("codec", "auto")
170+
if codec != "auto" and not _avif.encoder_codec_available(codec):
171+
msg = "Invalid saving codec"
172+
raise ValueError(msg)
173+
range_ = info.get("range", "full")
174+
tile_rows_log2 = info.get("tile_rows", 0)
175+
tile_cols_log2 = info.get("tile_cols", 0)
176+
alpha_premultiplied = bool(info.get("alpha_premultiplied", False))
177+
autotiling = bool(info.get("autotiling", tile_rows_log2 == tile_cols_log2 == 0))
178+
179+
icc_profile = info.get("icc_profile", im.info.get("icc_profile"))
180+
exif_orientation = 1
181+
if exif := info.get("exif"):
182+
if isinstance(exif, Image.Exif):
183+
exif_data = exif
184+
else:
185+
exif_data = Image.Exif()
186+
exif_data.load(exif)
187+
if ExifTags.Base.Orientation in exif_data:
188+
exif_orientation = exif_data.pop(ExifTags.Base.Orientation)
189+
exif = exif_data.tobytes() if exif_data else b""
190+
elif isinstance(exif, Image.Exif):
191+
exif = exif_data.tobytes()
192+
193+
xmp = info.get("xmp")
194+
195+
if isinstance(xmp, str):
196+
xmp = xmp.encode("utf-8")
197+
198+
advanced = info.get("advanced")
199+
if advanced is not None:
200+
if isinstance(advanced, dict):
201+
advanced = advanced.items()
202+
try:
203+
advanced = tuple(advanced)
204+
except TypeError:
205+
invalid = True
206+
else:
207+
invalid = any(not isinstance(v, tuple) or len(v) != 2 for v in advanced)
208+
if invalid:
209+
msg = (
210+
"advanced codec options must be a dict of key-value string "
211+
"pairs or a series of key-value two-tuples"
212+
)
213+
raise ValueError(msg)
214+
215+
# Setup the AVIF encoder
216+
enc = _avif.AvifEncoder(
217+
im.size,
218+
subsampling,
219+
quality,
220+
speed,
221+
max_threads,
222+
codec,
223+
range_,
224+
tile_rows_log2,
225+
tile_cols_log2,
226+
alpha_premultiplied,
227+
autotiling,
228+
icc_profile or b"",
229+
exif or b"",
230+
exif_orientation,
231+
xmp or b"",
232+
advanced,
233+
)
234+
235+
# Add each frame
236+
frame_idx = 0
237+
frame_duration = 0
238+
cur_idx = im.tell()
239+
is_single_frame = total == 1
240+
try:
241+
for ims in [im] + append_images:
242+
# Get number of frames in this image
243+
nfr = getattr(ims, "n_frames", 1)
244+
245+
for idx in range(nfr):
246+
ims.seek(idx)
247+
248+
# Make sure image mode is supported
249+
frame = ims
250+
rawmode = ims.mode
251+
if ims.mode not in {"RGB", "RGBA"}:
252+
rawmode = "RGBA" if ims.has_transparency_data else "RGB"
253+
frame = ims.convert(rawmode)
254+
255+
# Update frame duration
256+
if isinstance(duration, (list, tuple)):
257+
frame_duration = duration[frame_idx]
258+
else:
259+
frame_duration = duration
260+
261+
# Append the frame to the animation encoder
262+
enc.add(
263+
frame.tobytes("raw", rawmode),
264+
frame_duration,
265+
frame.size,
266+
rawmode,
267+
is_single_frame,
268+
)
269+
270+
# Update frame index
271+
frame_idx += 1
272+
273+
if not save_all:
274+
break
275+
276+
finally:
277+
im.seek(cur_idx)
278+
279+
# Get the final output from the encoder
280+
data = enc.finish()
281+
if data is None:
282+
msg = "cannot write file as AVIF (encoder returned None)"
283+
raise OSError(msg)
284+
285+
fp.write(data)
286+
287+
288+
Image.register_open(AvifImageFile.format, AvifImageFile, _accept)
289+
if SUPPORTED:
290+
Image.register_save(AvifImageFile.format, _save)
291+
Image.register_save_all(AvifImageFile.format, _save_all)
292+
Image.register_extensions(AvifImageFile.format, [".avif", ".avifs"])
293+
Image.register_mime(AvifImageFile.format, "image/avif")

0 commit comments

Comments
 (0)