diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 801d8a6..295a2bb 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,9 +1,12 @@ Release History =============== -0.8 (not yet released) ----------------------- +0.8 (2017-05-06) +---------------- * updated command line. All commands are now prefixed with *stegano-*; +* improved type hints; +* it is possible to load and save images from and to file objects (BytesIO); +* improved checks when revealing a message with the lsbset module fails. 0.7.1 (2017-05-05) ------------------ diff --git a/docs/conf.py b/docs/conf.py index 17d73d8..33cd492 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -48,9 +48,9 @@ copyright = u'2012-2017, Cédric Bonhomme' # built documents. # # The short X.Y version. -version = '0.7' +version = '0.8' # The full version, including alpha/beta/rc tags. -release = '0.7.1' +release = '0.8' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/setup.py b/setup.py index 2e1dce1..c9ce7df 100644 --- a/setup.py +++ b/setup.py @@ -36,7 +36,7 @@ with open('CHANGELOG.rst', 'r') as f: setup( name='Stegano', - version='0.7.1', + version='0.8', author='Cédric Bonhomme', author_email='cedric@cedricbonhomme.org', packages=packages, diff --git a/stegano/lsb/lsb.py b/stegano/lsb/lsb.py index 2e5a3de..b952329 100755 --- a/stegano/lsb/lsb.py +++ b/stegano/lsb/lsb.py @@ -28,12 +28,13 @@ __license__ = "GPLv3" import sys from PIL import Image +from typing import Union, IO from stegano import tools -def hide(input_image_file: str, - message, - encoding='UTF-8', +def hide(input_image: Union[str, IO[bytes]], + message: str, + encoding: str = 'UTF-8', auto_convert_rgb: bool = False): """Hide a message (string) in an image with the LSB (Least Significant Bit) technique. @@ -41,7 +42,7 @@ def hide(input_image_file: str, message_length = len(message) assert message_length != 0, "message length is zero" - img = Image.open(input_image_file) + img = Image.open(input_image) if img.mode not in ['RGB', 'RGBA']: if not auto_convert_rgb: @@ -92,10 +93,10 @@ def hide(input_image_file: str, return encoded -def reveal(input_image_file, encoding='UTF-8'): +def reveal(input_image: Union[str, IO[bytes]], encoding='UTF-8'): """Find a message in an image (with the LSB technique). """ - img = Image.open(input_image_file) + img = Image.open(input_image) width, height = img.size buff, count = 0, 0 bitab = [] diff --git a/stegano/lsbset/lsbset.py b/stegano/lsbset/lsbset.py index 9ebdc9b..d76697a 100644 --- a/stegano/lsbset/lsbset.py +++ b/stegano/lsbset/lsbset.py @@ -28,22 +28,23 @@ __license__ = "GPLv3" import sys from PIL import Image +from typing import Union, Iterator, IO from stegano import tools from . import generators -def hide(input_image_file, - message, - generator, - encoding='UTF-8', - auto_convert_rgb=False): +def hide(input_image: Union[str, IO[bytes]], + message: str, + generator: Iterator[int], + encoding: str = 'UTF-8', + auto_convert_rgb: bool = False): """Hide a message (string) in an image with the LSB (Least Significant Bit) technique. """ message_length = len(message) assert message_length != 0, "message length is zero" - img = Image.open(input_image_file) + img = Image.open(input_image) if img.mode not in ['RGB', 'RGBA']: if not auto_convert_rgb: @@ -94,10 +95,12 @@ def hide(input_image_file, return encoded -def reveal(input_image_file, generator, encoding='UTF-8'): +def reveal(input_image: Union[str, IO[bytes]], + generator: Iterator[int], + encoding: str = 'UTF-8'): """Find a message in an image (with the LSB technique). """ - img = Image.open(input_image_file) + img = Image.open(input_image) img_list = list(img.getdata()) width, height = img.size buff, count = 0, 0 @@ -114,9 +117,9 @@ def reveal(input_image_file, generator, encoding='UTF-8'): bitab.append(chr(buff)) buff, count = 0, 0 if bitab[-1] == ":" and limit == None: - try: + if "".join(bitab[:-1]).isdigit(): limit = int("".join(bitab[:-1])) - except: - pass + else: + raise IndexError("Impossible to detect message.") if len(bitab)-len(str(limit))-1 == limit : return "".join(bitab)[len(str(limit))+1:] diff --git a/stegano/red/red.py b/stegano/red/red.py index f75b5ad..a871e4d 100755 --- a/stegano/red/red.py +++ b/stegano/red/red.py @@ -28,8 +28,9 @@ __license__ = "GPLv3" import sys from PIL import Image +from typing import Union, IO -def hide(input_image_file, message): +def hide(input_image: Union[str, IO[bytes]], message: str): """ Hide a message (string) in an image. @@ -40,7 +41,7 @@ def hide(input_image_file, message): message_length = len(message) assert message_length != 0, "message message_length is zero" assert message_length < 255, "message is too long" - img = Image.open(input_image_file) + img = Image.open(input_image) # Use a copy of image to hide the text in encoded = img.copy() width, height = img.size @@ -61,7 +62,7 @@ def hide(input_image_file, message): img.close() return encoded -def reveal(input_image_file): +def reveal(input_image: Union[str, IO[bytes]]): """ Find a message in an image. @@ -69,7 +70,7 @@ def reveal(input_image_file): hidden message characters (ASCII values). The red value of the first pixel is used for message_length of string. """ - img = Image.open(input_image_file) + img = Image.open(input_image) width, height = img.size message = "" index = 0