Skip to content

Commit

Permalink
Test stock pyheif, drop older pyheif versions
Browse files Browse the repository at this point in the history
  • Loading branch information
homm committed Sep 10, 2024
1 parent a1038de commit 1cb27a7
Show file tree
Hide file tree
Showing 7 changed files with 28 additions and 56 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/Check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ jobs:
python: ['3.8', '3.11']
pillow: [prod, latest]
libheif: ['1.16.2-6ee6762-3f6b709', '1.18.2-bf35e9e-47f4fc0']
pyheif: ['', '0.7.1']
pyheif: ['', '0.8.0']
exclude:
- python: '3.11'
pyheif: '0.7.1'
pyheif: '0.8.0'
- libheif: '1.18.2-bf35e9e-47f4fc0'
pyheif: '0.7.1'
pyheif: '0.8.0'

steps:
- uses: actions/checkout@v2
Expand Down
11 changes: 2 additions & 9 deletions HeifImagePlugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,6 @@
from pyheif.error import HeifError


try:
from pyheif.transformations import Transformations
except ImportError:
Transformations = None


@dataclass
class LibheifError:
code: int
Expand Down Expand Up @@ -159,7 +153,7 @@ def _open_heif_file(self, apply_transformations):

def _open(self):
self.tile = []
self.heif_file = self._open_heif_file(Transformations is None)
self.heif_file = self._open_heif_file(False)

def load(self):
heif_file, self.heif_file = self.heif_file, None
Expand All @@ -183,8 +177,7 @@ def load(self):
self.load_prepare()

if heif_file.data:
if Transformations is not None:
heif_file = _crop_heif_file(heif_file)
heif_file = _crop_heif_file(heif_file)
self.frombytes(heif_file.data, "raw", (self.mode, heif_file.stride))

heif_file.data = None
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ This is not a big library but if you want to contribute is very easy!

## Changelog

### 0.6.3
### 0.7.0

* Depends on pyheif>=0.8.0
* Depends on pyheif>=0.8.0, drop older versions support

### 0.6.2

Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from setuptools import setup


__version__ = '0.6.3'
__version__ = '0.7.0'

github_url = 'https://github.com/uploadcare'
package_name = 'heif-image-plugin'
Expand Down
3 changes: 2 additions & 1 deletion tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ def avg_diff(im1, im2, *, threshold=0):
size = im1.width * im1.height

histos = [
ImageMath.eval("abs(ch1 - ch2)", ch1=ch1, ch2=ch2).convert('L').histogram()
ImageMath.unsafe_eval(
"abs(ch1 - ch2)", ch1=ch1, ch2=ch2).convert('L').histogram()
for ch1, ch2 in zip(im1.split(), im2.split())
]
return [
Expand Down
28 changes: 13 additions & 15 deletions tests/test_reading.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
import pytest
from PIL import Image, ImageCms, ImageOps
from pyheif.error import HeifError
from pyheif.transformations import Transformations

from HeifImagePlugin import Transformations, check_heif_magic
from HeifImagePlugin import check_heif_magic

from . import avg_diff, respath

Expand Down Expand Up @@ -69,8 +70,7 @@ def test_open_image_metadata(open_mock):
m.size = (10, 20)
m.mode = 'RGB'
m.data = b'rgb' * 10 * 20
if Transformations is not None:
m.transformations = Transformations(10, 20)
m.transformations = Transformations(10, 20)
m.metadata = [
{'type': 'foo', 'data': 'bar'},
{'type': 'bar', 'data': 'foo'},
Expand Down Expand Up @@ -102,25 +102,23 @@ def test_check_heif_magic_wrong():
def test_orientation(orientation, orientation_ref_image):
image = Image.open(respath('orientation', f'Landscape_{orientation}.heic'))

if Transformations is not None:
# There should be exif in each image, even if Orientation is 0
assert 'exif' in image.info
# There should be exif in each image, even if Orientation is 0
assert 'exif' in image.info

# There should be Orientation tag for each image
exif = image.getexif()
assert 0x0112 in exif
# There should be Orientation tag for each image
exif = image.getexif()
assert 0x0112 in exif

# And this orientation should be the same as in filename
assert exif[0x0112] == orientation
# And this orientation should be the same as in filename
assert exif[0x0112] == orientation

# Transposed image shoud be Landscape
transposed = ImageOps.exif_transpose(image)
assert transposed.size == (600, 450)

if Transformations is not None:
# Image should change after transposition
if orientation != 1:
assert image != transposed
# Image should change after transposition
if orientation != 1:
assert image != transposed

# The average diff between transposed and original image should be small
avg_diffs = avg_diff(transposed, orientation_ref_image, threshold=20)
Expand Down
30 changes: 5 additions & 25 deletions tests/test_transformations.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,12 @@
from unittest import mock

import pyheif
import pytest
from PIL import Image
from pyheif import open as pyheif_open

from HeifImagePlugin import Transformations
from pyheif.transformations import Transformations

from . import avg_diff, respath


skip_no_transformations = pytest.mark.skipif(
Transformations is None,
reason="pyheif doesn't support transformations")

skip_libheif_not_16 = pytest.mark.skipif(
pyheif.libheif_version() < '1.16.0',
reason="libheif < 1.16.0 can't decode odd sizes")


def open_with_custom_meta(path, *, exif_data=None, exif=None, crop=None, orientation=0):
def my_pyheif_open(*args, **kwargs):
nonlocal exif_data
Expand All @@ -32,11 +20,10 @@ def my_pyheif_open(*args, **kwargs):
heif.metadata = [{'type': 'Exif', 'data': exif_data}]
else:
heif.metadata = None
if Transformations is not None:
heif.transformations = Transformations(*heif.size)
heif.transformations.orientation_tag = orientation
if crop:
heif.transformations.crop = crop
heif.transformations = Transformations(*heif.size)
heif.transformations.orientation_tag = orientation
if crop:
heif.transformations.crop = crop
return heif

with mock.patch('pyheif.open') as open_mock:
Expand All @@ -52,14 +39,12 @@ def test_no_orientation_and_no_exif():
assert 'exif' not in image.info


@skip_no_transformations
def test_empty_exif():
image = open_with_custom_meta(respath('test2.heic'), exif_data=b'', orientation=1)
assert 'exif' in image.info
assert image.getexif()[274] == 1


@skip_no_transformations
def test_broken_exif():
broken = b'Exif\x00\x00II*\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00'
image = open_with_custom_meta(respath('test2.heic'),
Expand All @@ -68,7 +53,6 @@ def test_broken_exif():
assert image.getexif()[274] == 1


@skip_no_transformations
def test_orientation_and_no_exif():
image = open_with_custom_meta(respath('test2.heic'), orientation=7)

Expand All @@ -84,7 +68,6 @@ def test_no_orientation_and_exif_with_rotation():
assert image.getexif()[274] == 7


@skip_no_transformations
def test_orientation_and_exif_with_rotation():
# Orientation tag from file should suppress Exif value
image = open_with_custom_meta(
Expand All @@ -94,7 +77,6 @@ def test_orientation_and_exif_with_rotation():
assert image.getexif()[274] == 1


@skip_no_transformations
def test_orientation_and_exif_without_rotation():
image = open_with_custom_meta(
respath('test2.heic'), orientation=1, exif={270: "Sample image"})
Expand All @@ -103,7 +85,6 @@ def test_orientation_and_exif_without_rotation():
assert image.getexif()[274] == 1


@skip_no_transformations
def test_crop_on_load():
ref_image = Image.open(respath('test2.heic'))
assert ref_image.size == (1280, 720)
Expand All @@ -117,7 +98,6 @@ def test_crop_on_load():
assert image.copy() == ref_image.crop((99, 33, 611, 289))


@skip_libheif_not_16
def test_fallback_to_transforms():
# Image with 695x472 color and 696x472 alpha with crop
image = Image.open(respath('unreadable-wo-transf.heic'))
Expand Down

0 comments on commit 1cb27a7

Please sign in to comment.