Commit e479a8e4 authored by Chris Lamb's avatar Chris Lamb 💬

Tidy comparators.{gif,image,png}

Gbp-Dch: ignore
Signed-off-by: Chris Lamb's avatarChris Lamb <lamby@debian.org>
parent b799a145
......@@ -18,16 +18,16 @@
# along with diffoscope. If not, see <https://www.gnu.org/licenses/>.
import re
import subprocess
import logging
import subprocess
from diffoscope.tools import tool_required
from diffoscope.difference import Difference
from diffoscope.config import Config
from diffoscope.difference import Difference
from .image import pixel_difference, flicker_difference, same_size
from .utils.file import File
from .utils.command import Command
from .image import pixel_difference, flicker_difference, same_size
logger = logging.getLogger(__name__)
......@@ -47,20 +47,25 @@ class Gifbuild(Command):
return b""
return line
@tool_required('identify')
def is_image_static(image):
try:
return subprocess.check_output((
'identify',
'-format', '%n',
image.path)) == b'1'
image.path,
)) == b'1'
except subprocess.CalledProcessError:
return False
def can_compose_gif_images(image1, image2):
return same_size(image1, image2) and is_image_static(image1) and \
return same_size(image1, image2) and \
is_image_static(image1) and \
is_image_static(image2)
class GifFile(File):
RE_FILE_TYPE = re.compile(r'^GIF image data\b')
......@@ -69,14 +74,16 @@ class GifFile(File):
Gifbuild,
self.path,
other.path,
source='gifbuild',
source="gifbuild",
)
differences = [gifbuild_diff]
if gifbuild_diff is not None and Config().compute_visual_diffs and \
can_compose_gif_images(self, other):
try:
logger.debug(
'Generating visual difference for %s and %s',
"Generating visual difference for %s and %s",
self.path,
other.path,
)
......@@ -84,13 +91,14 @@ class GifFile(File):
None,
self.path,
other.path,
source='Image content',
source="Image content",
)
content_diff.add_visuals([
pixel_difference(self.path, other.path),
flicker_difference(self.path, other.path),
])
differences.append(content_diff)
except subprocess.CalledProcessError: #noqa
except subprocess.CalledProcessError: # noqa
pass
return differences
......@@ -18,14 +18,14 @@
# along with diffoscope. If not, see <https://www.gnu.org/licenses/>.
import re
import subprocess
import base64
import logging
import subprocess
from diffoscope.config import Config
from diffoscope.tools import tool_required
from diffoscope.tempfiles import get_named_temporary_file
from diffoscope.difference import Difference, VisualDifference
from diffoscope.config import Config
from .utils.file import File
from .utils.command import Command
......@@ -49,6 +49,7 @@ class Img2Txt(Command):
# Strip ANSI escapes
return re_ansi_escapes.sub('', line.decode('utf-8')).encode('utf-8')
class Identify(Command):
ATTRIBUTES = (
'Image format: %m',
......@@ -82,38 +83,58 @@ class Identify(Command):
self.path,
]
@tool_required('compare')
def pixel_difference(image1_path, image2_path):
compared_filename = get_named_temporary_file(suffix='.png').name
try:
subprocess.check_call(('compare', image1_path, image2_path,
'-compose', 'src', compared_filename))
subprocess.check_call((
'compare',
image1_path,
image2_path,
'-compose', 'src',
compared_filename,
))
except subprocess.CalledProcessError as e:
# ImageMagick's `compare` will return 1 if images are different
if e.returncode == 1:
pass
content = base64.b64encode(open(compared_filename, 'rb').read())
content = content.decode('utf8')
datatype = 'image/png;base64'
result = VisualDifference(datatype, content, "Pixel difference")
return result
with open(compared_filename, 'rb') as f:
content = base64.b64encode(f.read()).decode('utf8')
return VisualDifference('image/png;base64', content, "Pixel difference")
@tool_required('convert')
def flicker_difference(image1_path, image2_path):
compared_filename = get_named_temporary_file(suffix='.gif').name
subprocess.check_call(
('convert', '-delay', '50', image1_path, image2_path,
'-loop', '0', '-compose', 'difference', compared_filename))
content = base64.b64encode(open(compared_filename, 'rb').read())
content = content.decode('utf8')
datatype = 'image/gif;base64'
result = VisualDifference(datatype, content, "Flicker difference")
return result
subprocess.check_call((
'convert',
'-delay', '50',
image1_path,
image2_path,
'-loop', '0',
'-compose', 'difference',
compared_filename,
))
with open(compared_filename, 'rb') as f:
content = base64.b64encode(f.read()).decode('utf8')
return VisualDifference('image/gif;base64', content, "Flicker difference")
@tool_required('identify')
def get_image_size(image_path):
return subprocess.check_output(('identify', '-format',
'%[h]x%[w]', image_path))
return subprocess.check_output((
'identify',
'-format', '%[h]x%[w]',
image_path,
))
def same_size(image1, image2):
try:
......@@ -121,6 +142,7 @@ def same_size(image1, image2):
except subprocess.CalledProcessError: # noqa
return False
class JPEGImageFile(File):
RE_FILE_TYPE = re.compile(r'\bJPEG image data\b')
......@@ -135,7 +157,7 @@ class JPEGImageFile(File):
same_size(self, other):
try:
logger.debug(
'Generating visual difference for %s and %s',
"Generating visual difference for %s and %s",
self.path,
other.path,
)
......@@ -155,6 +177,7 @@ class JPEGImageFile(File):
),
]
class ICOImageFile(File):
RE_FILE_TYPE = re.compile(r'\bMS Windows icon resource\b')
......@@ -177,7 +200,7 @@ class ICOImageFile(File):
same_size(self, other):
if get_image_size(self.path) == get_image_size(other.path):
logger.debug(
'Generating visual difference for %s and %s',
"Generating visual difference for %s and %s",
self.path,
other.path,
)
......
......@@ -18,17 +18,17 @@
# along with diffoscope. If not, see <https://www.gnu.org/licenses/>.
import re
import logging
import functools
import subprocess
import logging
from diffoscope.config import Config
from diffoscope.tools import tool_required
from diffoscope.difference import Difference
from diffoscope.config import Config
from .image import pixel_difference, flicker_difference, same_size
from .utils.file import File
from .utils.command import Command
from .image import pixel_difference, flicker_difference, same_size
logger = logging.getLogger(__name__)
......@@ -50,11 +50,12 @@ class PngFile(File):
def compare_details(self, other, source=None):
sng_diff = Difference.from_command(Sng, self.path, other.path, source='sng')
differences = [sng_diff]
if sng_diff is not None and Config().compute_visual_diffs and \
same_size(self, other):
try:
logger.debug(
'Generating visual difference for %s and %s',
"Generating visual difference for %s and %s",
self.path,
other.path,
)
......@@ -71,4 +72,5 @@ class PngFile(File):
differences.append(content_diff)
except subprocess.CalledProcessError: # noqa
pass
return differences
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment