Skip to content

Commit

Permalink
Merge pull request #78 from AnonymouX47/prevent-zero-size
Browse files Browse the repository at this point in the history
Prevent zero render size
  • Loading branch information
AnonymouX47 authored Feb 27, 2023
2 parents 10ba5ad + 204d1fe commit 8a442e7
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 49 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `None` is no longer a valid value.
- The lower bound of the valid value range is now `-(2**31 - 1)`.
- Extended `ITerm2Image.clear()` ([807a9ec]).
- Computed image size and `image.rendered_size` (regardless of the value of `image.scale`) can no longer be null (contain `0`) ([#78]).
- No more "Image size or scale too small" error at render time.

### Removed
- The CLI and TUI ([#72]).
Expand All @@ -45,6 +47,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
[#72]: https://github.com/AnonymouX47/term-image/pull/72
[#73]: https://github.com/AnonymouX47/term-image/pull/73
[#74]: https://github.com/AnonymouX47/term-image/pull/74
[#78]: https://github.com/AnonymouX47/term-image/pull/78
[b4533d5]: https://github.com/AnonymouX47/term-image/commit/b4533d5697d41fe0742c2ac895077da3b8d889dc
[97eceab]: https://github.com/AnonymouX47/term-image/commit/97eceab77e7448a18281aa6edb3fa8ec9e6564c5
[807a9ec]: https://github.com/AnonymouX47/term-image/commit/807a9ecad717e46621a5214dbf849369d3afbc0b
Expand Down
48 changes: 28 additions & 20 deletions src/term_image/image/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,8 @@ def n_frames(self) -> int:
else self._size
)[1]
* self._scale[1]
),
)
or 1,
doc="""
The **scaled** height of the image.
Expand All @@ -434,15 +435,18 @@ def n_frames(self) -> int:
rendered_size = property(
lambda self: tuple(
map(
round,
lambda x: x or 1,
map(
mul,
(
self._valid_size(self._size, None)
if isinstance(self._size, Size)
else self._size
round,
map(
mul,
(
self._valid_size(self._size, None)
if isinstance(self._size, Size)
else self._size
),
self._scale,
),
self._scale,
),
)
),
Expand All @@ -464,7 +468,8 @@ def n_frames(self) -> int:
else self._size
)[0]
* self._scale[0]
),
)
or 1,
doc="""
The **scaled** width of the image.
Expand Down Expand Up @@ -735,8 +740,7 @@ def draw(
TypeError: An argument is of an inappropriate type.
ValueError: An argument is of an appropriate type but has an
unexpected/invalid value.
ValueError: Unable to convert image.
ValueError: Image size or :term:`scale` too small.
ValueError: Unable to convert or resize image.
term_image.exceptions.InvalidSizeError: The image's :term:`rendered size`
can not fit into the :term:`available terminal size <available size>`.
term_image.exceptions.StyleError: Unrecognized style-specific parameter(s).
Expand Down Expand Up @@ -1577,6 +1581,7 @@ def convert_resize_img(mode: str):
prev_img = img
try:
img = img.convert(mode)
# Possible for images in some modes e.g "La"
except Exception as e:
raise ValueError("Unable to convert image") from e
finally:
Expand All @@ -1587,8 +1592,9 @@ def convert_resize_img(mode: str):
prev_img = img
try:
img = img.resize(size, Image.Resampling.BOX)
except ValueError as e:
raise ValueError("Image size or scale too small") from e
# Highly unlikely since render size can never be zero
except Exception as e:
raise ValueError("Unable to resize image") from e
finally:
if frame_img is not prev_img is not self._source:
prev_img.close()
Expand Down Expand Up @@ -1893,18 +1899,20 @@ def _valid_size(
)
elif Size.FIT_TO_WIDTH in (width, height):
return (
self._pixels_cols(pixels=max_width),
self._pixels_cols(pixels=max_width) or 1,
self._pixels_lines(
pixels=round(
self._width_height_px(w=max_width) * self._pixel_ratio
)
),
)
or 1,
)

if Size.ORIGINAL in (width, height):
return (
self._pixels_cols(pixels=ori_width),
self._pixels_lines(pixels=round(ori_height * self._pixel_ratio)),
self._pixels_cols(pixels=ori_width) or 1,
self._pixels_lines(pixels=round(ori_height * self._pixel_ratio))
or 1,
)

# The smaller fraction will fit on both axis.
Expand Down Expand Up @@ -1936,8 +1944,8 @@ def _valid_size(
# Round the width
width_px = round(width_px)
return (
self._pixels_cols(pixels=width_px),
self._pixels_lines(pixels=height_px),
self._pixels_cols(pixels=width_px) or 1,
self._pixels_lines(pixels=height_px) or 1,
)
elif width is None:
width_px = round(
Expand All @@ -1958,7 +1966,7 @@ def _valid_size(
f"'maxsize' {maxsize}"
)

return (width, height)
return (width or 1, height or 1)

def _width_height_px(
self, *, w: Optional[int] = None, h: Optional[int] = None
Expand Down
23 changes: 4 additions & 19 deletions tests/test_image/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -256,17 +256,17 @@ def test_rendered_size_height_width(self):
for value in range(1, 101):
scale = value / 100
image.scale = scale
assert image.rendered_width == round(_width * scale)
assert image.rendered_height == round(_height * scale)
assert 0 != image.rendered_width == (round(_width * scale) or 1)
assert 0 != image.rendered_height == (round(_height * scale) or 1)

# Random scales
for _ in range(100):
scale = random()
if scale == 0:
continue
image.scale = scale
assert image.rendered_width == round(_width * scale)
assert image.rendered_height == round(_height * scale)
assert 0 != image.rendered_width == (round(_width * scale) or 1)
assert 0 != image.rendered_height == (round(_height * scale) or 1)

image.scale = 1.0

Expand Down Expand Up @@ -569,21 +569,6 @@ def get_render_data(self, img=None, alpha=None, **kwargs):
img or self.trans._get_image(), alpha, **kwargs
)

def test_small_size_scale(self):
try:
for self.trans._size in ((1, 0), (0, 1), (0, 0)):
with pytest.raises(ValueError, match="too small"):
self.get_render_data(None)
finally:
self.trans.height = _size

try:
self.trans.scale = 0.0001
with pytest.raises(ValueError, match="too small"):
self.get_render_data(None)
finally:
self.trans.scale = 1.0

def test_alpha(self):

# float
Expand Down
4 changes: 2 additions & 2 deletions tests/test_image/test_block.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,8 @@ def test_scaled(self):
if scale == 0.0:
continue
self.trans.scale = scale
if 0 in self.trans.rendered_size:
continue
assert 0 not in self.trans.rendered_size

render = self.render_image(_ALPHA_THRESHOLD)
assert render.count("\n") + 1 == self.trans.rendered_height
assert all(
Expand Down
8 changes: 4 additions & 4 deletions tests/test_image/test_iterm2.py
Original file line number Diff line number Diff line change
Expand Up @@ -414,8 +414,8 @@ def test_scaled(self):
if scale == 0.0:
continue
self.trans.scale = scale
if 0 in self.trans.rendered_size:
continue

assert 0 not in self.trans.rendered_size
for ITerm2Image._TERM in supported_terminals:
self._test_image_size(self.trans, term=ITerm2Image._TERM)

Expand Down Expand Up @@ -699,8 +699,8 @@ def test_scaled(self):
if scale == 0.0:
continue
self.trans.scale = scale
if 0 in self.trans.rendered_size:
continue

assert 0 not in self.trans.rendered_size
for ITerm2Image._TERM in supported_terminals:
self._test_image_size(self.trans, term=ITerm2Image._TERM)

Expand Down
8 changes: 4 additions & 4 deletions tests/test_image/test_kitty.py
Original file line number Diff line number Diff line change
Expand Up @@ -455,8 +455,8 @@ def test_scaled(self):
if scale == 0.0:
continue
self.trans.scale = scale
if 0 in self.trans.rendered_size:
continue

assert 0 not in self.trans.rendered_size
self._test_image_size(self.trans)


Expand Down Expand Up @@ -660,8 +660,8 @@ def test_scaled(self):
if scale == 0.0:
continue
self.trans.scale = scale
if 0 in self.trans.rendered_size:
continue

assert 0 not in self.trans.rendered_size
self._test_image_size(self.trans)


Expand Down

0 comments on commit 8a442e7

Please sign in to comment.