diff --git a/.coveragerc b/.coveragerc
index 90b7cd3ea..cccb62754 100644
--- a/.coveragerc
+++ b/.coveragerc
@@ -23,4 +23,4 @@ omit =
# Tests/check_*.py
# Tests/createfontdatachunk.py
Tests/*
- # src/*
\ No newline at end of file
+ src/*
diff --git a/README.md b/README.md
index 1010c4705..a7d7e9f71 100644
--- a/README.md
+++ b/README.md
@@ -1,115 +1,136 @@
-
-
-
-
-# Pillow
-
-## Python Imaging Library (Fork)
-
-Pillow is the friendly PIL fork by [Jeffrey A. Clark and
-contributors](https://github.com/python-pillow/Pillow/graphs/contributors).
-PIL is the Python Imaging Library by Fredrik Lundh and contributors.
-As of 2019, Pillow development is
-[supported by Tidelift](https://tidelift.com/subscription/pkg/pypi-pillow?utm_source=pypi-pillow&utm_medium=readme&utm_campaign=enterprise).
-
-
-
- docs |
-
-
- |
-
-
- tests |
-
-
-
-
-
-
-
-
-
-
-
- |
-
-
- package |
-
-
-
-
-
-
- |
-
-
- social |
-
-
-
- |
-
-
-
-## Overview
-
-The Python Imaging Library adds image processing capabilities to your Python interpreter.
-
-This library provides extensive file format support, an efficient internal representation, and fairly powerful image processing capabilities.
-
-The core image library is designed for fast access to data stored in a few basic pixel formats. It should provide a solid foundation for a general image processing tool.
-
-## More Information
-
-- [Documentation](https://pillow.readthedocs.io/)
- - [Installation](https://pillow.readthedocs.io/en/latest/installation/basic-installation.html)
- - [Handbook](https://pillow.readthedocs.io/en/latest/handbook/index.html)
-- [Contribute](https://github.com/python-pillow/Pillow/blob/main/.github/CONTRIBUTING.md)
- - [Issues](https://github.com/python-pillow/Pillow/issues)
- - [Pull requests](https://github.com/python-pillow/Pillow/pulls)
-- [Release notes](https://pillow.readthedocs.io/en/stable/releasenotes/index.html)
-- [Changelog](https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst)
- - [Pre-fork](https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst#pre-fork)
-
-## Report a Vulnerability
-
-To report a security vulnerability, please follow the procedure described in the [Tidelift security policy](https://tidelift.com/docs/security).
+# Report for Assignment 1
+
+## Project chosen
+
+Name: Pillow
+
+URL of our repository: https://github.com/jovanovicisidora/Pillow-SEP.git
+
+URL of the original repo: https://github.com/python-pillow/Pillow.git
+
+Number of lines of code and the tool used to count it:
+- Tool used: coverage.py
+- Number of lines of code: 82 KLOC
+
+Programming language: Python
+
+## Coverage measurement
+
+### Existing tool
+
+
+
+
+
+We used Coverage.py. We executed the coverage tool by running the following command:
+
+`python3 -bb -m pytest -v -x -W always --cov PIL --cov Tests --cov-report term Tests $REVERSE`
+
+This resulted in the following output:
+
+
+
+### Your own coverage tool
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Each member of out group has chosen two functions and has instrumented our own coverage tool. For each function we
+created a dictionary with the branch ID as key, and a boolean as the value. If the branch was accessed by the tests,
+the boolean value would be changed from False to True. In order to calculate and display the coverage, all tests use
+the shared code in **conftest.py**.
+
+**1. Deekshu**
+
+**2. Duru**
+
+**3. Isidora**
+
+- Function 1: `_save()` from **SpiderImagePlugin.py**
+
+ [Link to the commit](https://github.com/jovanovicisidora/Pillow-SEP/commit/5701d33cbb789342ca781769d4ba7cd323c9255e#diff-44debbfd4d0c5a80130a15bdcd9e0b28c1b4fef6eda0eaaef48838c954589d15)
+
+
+
+- Function 2: `Bitstream.peek()` from **MpegImagePlugin.py**
+
+ [Link to the commit](https://github.com/jovanovicisidora/Pillow-SEP/commit/70f6735620d2f8e469cbe5b60a4586c5db95624a#diff-0272f0c6b5871be3364fe2062e50944fba30dad9625c74d13340de7d3ad8d367)
+
+
+
+**4. Sofija**
+
+## Coverage improvement
+
+### Individual tests
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+**1. Deekshu**
+
+**2. Duru**
+
+**3. Isidora**
+
+- Function 1: `_save()` from **SpiderImagePlugin.py**
+
+ [Link to the commit](https://github.com/jovanovicisidora/Pillow-SEP/commit/70f6735620d2f8e469cbe5b60a4586c5db95624a#diff-f0eb82b90cfc005f681c774b3bf87f19b1db010750e49f850883005f4f623202)
+
+
+
+
+
+- Function 2: `Bitstream.peek()` from **MpegImagePlugin.py**
+
+ [Link to the commit](https://github.com/jovanovicisidora/Pillow-SEP/commit/70f6735620d2f8e469cbe5b60a4586c5db95624a#diff-48e5b5451c5cab3fbb758ae58649082b62ae6f2850393a332949643d75bd4ad2)
+
+
+
+
+
+**4. Sofija**
+
+### Overall
+
+First we provide a screenshot of the old coverage results by running an existing tool:
+
+
+
+Here we show the improved overall coverage with all test modifications made by out group:
+
+
+
+## Statement of individual contributions
+
+Each group member had an equal contribution to the assignment. We first met together to determine
+how we can make a coverage tool that can be used across all functions (in conftest.py). Then, each
+member chose two functions to instrument our coverage tool on and to make/enhance tests for them.
+The specific functions each member chose can be seen in the report above.
diff --git a/README_original.md b/README_original.md
new file mode 100644
index 000000000..b4c6d2987
--- /dev/null
+++ b/README_original.md
@@ -0,0 +1,115 @@
+
+
+
+
+# Pillow
+
+## Python Imaging Library (Fork)
+
+Pillow is the friendly PIL fork by [Jeffrey A. Clark and
+contributors](https://github.com/python-pillow/Pillow/graphs/contributors).
+PIL is the Python Imaging Library by Fredrik Lundh and contributors.
+As of 2019, Pillow development is
+[supported by Tidelift](https://tidelift.com/subscription/pkg/pypi-pillow?utm_source=pypi-pillow&utm_medium=readme&utm_campaign=enterprise).
+
+
+
+ docs |
+
+
+ |
+
+
+ tests |
+
+
+
+
+
+
+
+
+
+
+
+ |
+
+
+ package |
+
+
+
+
+
+
+ |
+
+
+ social |
+
+
+
+ |
+
+
+
+## Overview
+
+The Python Imaging Library adds image processing capabilities to your Python interpreter.
+
+This library provides extensive file format support, an efficient internal representation, and fairly powerful image processing capabilities.
+
+The core image library is designed for fast access to data stored in a few basic pixel formats. It should provide a solid foundation for a general image processing tool.
+
+## More Information
+
+- [Documentation](https://pillow.readthedocs.io/)
+ - [Installation](https://pillow.readthedocs.io/en/latest/installation/basic-installation.html)
+ - [Handbook](https://pillow.readthedocs.io/en/latest/handbook/index.html)
+- [Contribute](https://github.com/python-pillow/Pillow/blob/main/.github/CONTRIBUTING.md)
+ - [Issues](https://github.com/python-pillow/Pillow/issues)
+ - [Pull requests](https://github.com/python-pillow/Pillow/pulls)
+- [Release notes](https://pillow.readthedocs.io/en/stable/releasenotes/index.html)
+- [Changelog](https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst)
+ - [Pre-fork](https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst#pre-fork)
+
+## Report a Vulnerability
+
+To report a security vulnerability, please follow the procedure described in the [Tidelift security policy](https://tidelift.com/docs/security).
diff --git a/Tests/test_file_mpeg.py b/Tests/test_file_mpeg.py
index 44895c9ba..af39e553a 100644
--- a/Tests/test_file_mpeg.py
+++ b/Tests/test_file_mpeg.py
@@ -6,6 +6,8 @@ import pytest
from PIL import Image, MpegImagePlugin
+from unittest.mock import MagicMock, patch
+
def test_identify() -> None:
# Arrange
@@ -37,3 +39,15 @@ def test_load() -> None:
# Act / Assert: cannot load
with pytest.raises(OSError):
im.load()
+
+
+def test_peek_with_negative_c() -> None:
+ fp = MagicMock()
+
+ return_values = [-1, 255]
+
+ with patch.object(MpegImagePlugin.BitStream, 'next', side_effect=return_values):
+ bitstream = MpegImagePlugin.BitStream(fp)
+ result = bitstream.peek(8)
+
+ assert result == 255
diff --git a/Tests/test_file_spider.py b/Tests/test_file_spider.py
index d8bf33f80..e614668d1 100644
--- a/Tests/test_file_spider.py
+++ b/Tests/test_file_spider.py
@@ -4,6 +4,9 @@ import tempfile
import warnings
from io import BytesIO
from pathlib import Path
+from unittest.mock import MagicMock, patch
+import unittest
+import struct
import pytest
@@ -162,3 +165,27 @@ def test_odd_size() -> None:
data.seek(0)
with Image.open(data) as im2:
assert_image_equal(im, im2)
+
+
+def test_seek_no_frame() -> None:
+ with Image.open(TEST_FILE) as im:
+ im.istack = 1
+ im.seek(0)
+
+
+def test_save_small_header() -> None:
+ width, height = 10, 10
+ im = Image.new("F", (width, height))
+
+ fp = BytesIO()
+
+ corrupted_header = [b'\x00' * 4] * 22
+
+ with patch("PIL.SpiderImagePlugin.makeSpiderHeader", return_value=corrupted_header):
+ try:
+ im.save(fp, format="SPIDER")
+ except OSError as e:
+ assert str(e) == "Error creating Spider header"
+ else:
+ assert False, "Expected an OSError due to corrupted header"
+
diff --git a/conftest.py b/conftest.py
index 260330c28..805c67409 100644
--- a/conftest.py
+++ b/conftest.py
@@ -4,6 +4,8 @@ import sys
from PIL import Image
from PIL import PdfParser
+from PIL import SpiderImagePlugin
+from PIL import MpegImagePlugin
from PIL import ImageCms
from PIL import McIdasImagePlugin
@@ -14,8 +16,10 @@ def calculate_coverage(test_name):
all_branches = {
"branches1": Image.branches,
"branches2": PdfParser.XrefTable.branches,
- "branches3": ImageCms.ImageCmsProfile.branches,
- "branches4": McIdasImagePlugin.McIdasImageFile.branches,
+ "branches3": SpiderImagePlugin.branches,
+ "branches4": MpegImagePlugin.BitStream.branches,
+ "branches5": ImageCms.ImageCmsProfile.branches,
+ "branches6": McIdasImagePlugin.McIdasImageFile.branches,
# Add more
}
@@ -49,4 +53,5 @@ def pytest_sessionfinish(session, exitstatus):
global test_name
coverage = calculate_coverage(test_name)
- print("\nBRANCH COVERAGE for", test_name, ":", coverage, "%\n")
\ No newline at end of file
+ print("\nBRANCH COVERAGE for", test_name, ":", coverage, "%\n")
+
diff --git a/libwebp-1.4.0.tar.gz b/libwebp-1.4.0.tar.gz
new file mode 100644
index 000000000..7034c045c
Binary files /dev/null and b/libwebp-1.4.0.tar.gz differ
diff --git a/myenv/lib64 b/myenv/lib64
new file mode 120000
index 000000000..7951405f8
--- /dev/null
+++ b/myenv/lib64
@@ -0,0 +1 @@
+lib
\ No newline at end of file
diff --git a/myenv/pyvenv.cfg b/myenv/pyvenv.cfg
new file mode 100644
index 000000000..b61212b29
--- /dev/null
+++ b/myenv/pyvenv.cfg
@@ -0,0 +1,5 @@
+home = /usr/bin
+include-system-site-packages = false
+version = 3.12.3
+executable = /usr/bin/python3.12
+command = /usr/bin/python3 -m venv /home/duru/Documents/Period_6/Pillow-SEP/myenv
diff --git a/pillowenv/lib64 b/pillowenv/lib64
new file mode 120000
index 000000000..7951405f8
--- /dev/null
+++ b/pillowenv/lib64
@@ -0,0 +1 @@
+lib
\ No newline at end of file
diff --git a/pillowenv/pyvenv.cfg b/pillowenv/pyvenv.cfg
new file mode 100644
index 000000000..5f2f98faa
--- /dev/null
+++ b/pillowenv/pyvenv.cfg
@@ -0,0 +1,5 @@
+home = /usr/bin
+include-system-site-packages = false
+version = 3.12.3
+executable = /usr/bin/python3.12
+command = /usr/bin/python3 -m venv /home/duru/Documents/Period_6/Pillow-SEP/pillowenv
diff --git a/report_images/isidora_images/[AFTER]_save.png b/report_images/isidora_images/[AFTER]_save.png
new file mode 100644
index 000000000..d41f380a5
Binary files /dev/null and b/report_images/isidora_images/[AFTER]_save.png differ
diff --git a/report_images/isidora_images/[AFTER]peek.png b/report_images/isidora_images/[AFTER]peek.png
new file mode 100644
index 000000000..6f7e76bd5
Binary files /dev/null and b/report_images/isidora_images/[AFTER]peek.png differ
diff --git a/report_images/isidora_images/[BEFORE]_save.png b/report_images/isidora_images/[BEFORE]_save.png
new file mode 100644
index 000000000..899a84c20
Binary files /dev/null and b/report_images/isidora_images/[BEFORE]_save.png differ
diff --git a/report_images/isidora_images/[BEFORE]overall_coverage.png b/report_images/isidora_images/[BEFORE]overall_coverage.png
new file mode 100644
index 000000000..9ff2e9a49
Binary files /dev/null and b/report_images/isidora_images/[BEFORE]overall_coverage.png differ
diff --git a/report_images/isidora_images/[BEFORE]peek.png b/report_images/isidora_images/[BEFORE]peek.png
new file mode 100644
index 000000000..ffb512a48
Binary files /dev/null and b/report_images/isidora_images/[BEFORE]peek.png differ
diff --git a/report_images/isidora_images/our_tool_peek.png b/report_images/isidora_images/our_tool_peek.png
new file mode 100644
index 000000000..936514252
Binary files /dev/null and b/report_images/isidora_images/our_tool_peek.png differ
diff --git a/report_images/isidora_images/our_tool_save.png b/report_images/isidora_images/our_tool_save.png
new file mode 100644
index 000000000..8313a3fec
Binary files /dev/null and b/report_images/isidora_images/our_tool_save.png differ
diff --git a/src/PIL/MpegImagePlugin.py b/src/PIL/MpegImagePlugin.py
index cf62cd87d..d6be8ed4d 100644
--- a/src/PIL/MpegImagePlugin.py
+++ b/src/PIL/MpegImagePlugin.py
@@ -21,8 +21,13 @@ from ._typing import SupportsRead
#
# Bitstream parser
-
class BitStream:
+ branches = {
+ "1": False,
+ "2": False,
+ "3": False,
+ }
+
def __init__(self, fp: SupportsRead[bytes]) -> None:
self.fp = fp
self.bits = 0
@@ -33,12 +38,19 @@ class BitStream:
def peek(self, bits: int) -> int:
while self.bits < bits:
+ BitStream.branches["1"] = True
c = self.next()
+
if c < 0:
+ BitStream.branches["2"] = True
self.bits = 0
continue
+ else:
+ BitStream.branches["3"] = True
+
self.bitbuffer = (self.bitbuffer << 8) + c
self.bits += 8
+
return self.bitbuffer >> (self.bits - bits) & (1 << bits) - 1
def skip(self, bits: int) -> None:
diff --git a/src/PIL/SpiderImagePlugin.py b/src/PIL/SpiderImagePlugin.py
index 14aff84e0..70edede19 100644
--- a/src/PIL/SpiderImagePlugin.py
+++ b/src/PIL/SpiderImagePlugin.py
@@ -42,6 +42,7 @@ from typing import IO, TYPE_CHECKING
from . import Image, ImageFile
+
def isInt(f):
try:
i = int(f)
@@ -55,6 +56,13 @@ def isInt(f):
iforms = [1, 3, -11, -12, -21, -22]
+branches = {
+ "1": False,
+ "2": False,
+ "3": False,
+ "4": False
+}
+
# There is no magic number to identify Spider files, so just check a
# series of header locations to see if they have reasonable values.
@@ -107,19 +115,23 @@ class SpiderImageFile(ImageFile.ImageFile):
self.bigendian = 1
t = struct.unpack(">27f", f) # try big-endian first
hdrlen = isSpiderHeader(t)
+
if hdrlen == 0:
self.bigendian = 0
t = struct.unpack("<27f", f) # little-endian
hdrlen = isSpiderHeader(t)
+
if hdrlen == 0:
msg = "not a valid Spider file"
raise SyntaxError(msg)
+
except struct.error as e:
msg = "not a valid Spider file"
raise SyntaxError(msg) from e
h = (99,) + t # add 1 value : spider header index starts at 1
iform = int(h[5])
+
if iform != 1:
msg = "not a Spider 2D image"
raise SyntaxError(msg)
@@ -176,8 +188,10 @@ class SpiderImageFile(ImageFile.ImageFile):
if self.istack == 0:
msg = "attempt to seek in a non-stack file"
raise EOFError(msg)
+
if not self._seek_check(frame):
return
+
self.stkoffset = self.hdrlen + frame * (self.hdrlen + self.imgbytes)
self.fp = self._fp
self.fp.seek(self.stkoffset)
@@ -265,12 +279,18 @@ def makeSpiderHeader(im: Image.Image) -> list[bytes]:
def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None:
if im.mode[0] != "F":
+ branches["1"] = True
im = im.convert("F")
+ else:
+ branches["2"] = True
hdr = makeSpiderHeader(im)
if len(hdr) < 256:
+ branches["3"] = True
msg = "Error creating Spider header"
raise OSError(msg)
+ else:
+ branches["4"] = True
# write the SPIDER header
fp.writelines(hdr)