{
    "file_diffs": [
        {
            "old_file_content": "import io\nimport os\nimport os.path\nimport tempfile\nimport time\n\nimport pytest\n\nfrom PIL import Image, PdfParser, features\n\nfrom .helper import hopper, mark_if_feature_version, skip_unless_feature\n\n\ndef helper_save_as_pdf(tmp_path, mode, **kwargs):\n    # Arrange\n    im = hopper(mode)\n    outfile = str(tmp_path / (\"temp_\" + mode + \".pdf\"))\n\n    # Act\n    im.save(outfile, **kwargs)\n\n    # Assert\n    assert os.path.isfile(outfile)\n    assert os.path.getsize(outfile) > 0\n    with PdfParser.PdfParser(outfile) as pdf:\n        if kwargs.get(\"append_images\", False) or kwargs.get(\"append\", False):\n            assert len(pdf.pages) > 1\n        else:\n            assert len(pdf.pages) > 0\n    with open(outfile, \"rb\") as fp:\n        contents = fp.read()\n    size = tuple(\n        float(d) for d in contents.split(b\"/MediaBox [ 0 0 \")[1].split(b\"]\")[0].split()\n    )\n    assert im.size == size\n\n    return outfile\n\n\n@pytest.mark.parametrize(\"mode\", (\"L\", \"P\", \"RGB\", \"CMYK\"))\ndef test_save(tmp_path, mode):\n    helper_save_as_pdf(tmp_path, mode)\n\n\n@skip_unless_feature(\"jpg_2000\")\n@pytest.mark.parametrize(\"mode\", (\"LA\", \"RGBA\"))\ndef test_save_alpha(tmp_path, mode):\n    helper_save_as_pdf(tmp_path, mode)\n\n\ndef test_monochrome(tmp_path):\n    # Arrange\n    mode = \"1\"\n\n    # Act / Assert\n    outfile = helper_save_as_pdf(tmp_path, mode)\n    assert os.path.getsize(outfile) < (5000 if features.check(\"libtiff\") else 15000)\n\n\ndef test_unsupported_mode(tmp_path):\n    im = hopper(\"PA\")\n    outfile = str(tmp_path / \"temp_PA.pdf\")\n\n    with pytest.raises(ValueError):\n        im.save(outfile)\n\n\ndef test_resolution(tmp_path):\n    im = hopper()\n\n    outfile = str(tmp_path / \"temp.pdf\")\n    im.save(outfile, resolution=150)\n\n    with open(outfile, \"rb\") as fp:\n        contents = fp.read()\n\n    size = tuple(\n        float(d)\n        for d in contents.split(b\"stream\\nq \")[1].split(b\" 0 0 cm\")[0].split(b\" 0 0 \")\n    )\n    assert size == (61.44, 61.44)\n\n    size = tuple(\n        float(d) for d in contents.split(b\"/MediaBox [ 0 0 \")[1].split(b\"]\")[0].split()\n    )\n    assert size == (61.44, 61.44)\n\n\n@pytest.mark.parametrize(\n    \"params\",\n    (\n        {\"dpi\": (75, 150)},\n        {\"dpi\": (75, 150), \"resolution\": 200},\n    ),\n)\ndef test_dpi(params, tmp_path):\n    im = hopper()\n\n    outfile = str(tmp_path / \"temp.pdf\")\n    im.save(outfile, **params)\n\n    with open(outfile, \"rb\") as fp:\n        contents = fp.read()\n\n    size = tuple(\n        float(d)\n        for d in contents.split(b\"stream\\nq \")[1].split(b\" 0 0 cm\")[0].split(b\" 0 0 \")\n    )\n    assert size == (122.88, 61.44)\n\n    size = tuple(\n        float(d) for d in contents.split(b\"/MediaBox [ 0 0 \")[1].split(b\"]\")[0].split()\n    )\n    assert size == (122.88, 61.44)\n\n\n@mark_if_feature_version(\n    pytest.mark.valgrind_known_error, \"libjpeg_turbo\", \"2.0\", reason=\"Known Failing\"\n)\ndef test_save_all(tmp_path):\n    # Single frame image\n    helper_save_as_pdf(tmp_path, \"RGB\", save_all=True)\n\n    # Multiframe image\n    with Image.open(\"Tests/images/dispose_bgnd.gif\") as im:\n        outfile = str(tmp_path / \"temp.pdf\")\n        im.save(outfile, save_all=True)\n\n        assert os.path.isfile(outfile)\n        assert os.path.getsize(outfile) > 0\n\n        # Append images\n        ims = [hopper()]\n        im.copy().save(outfile, save_all=True, append_images=ims)\n\n        assert os.path.isfile(outfile)\n        assert os.path.getsize(outfile) > 0\n\n        # Test appending using a generator\n        def im_generator(ims):\n            yield from ims\n\n        im.save(outfile, save_all=True, append_images=im_generator(ims))\n\n    assert os.path.isfile(outfile)\n    assert os.path.getsize(outfile) > 0\n\n    # Append JPEG images\n    with Image.open(\"Tests/images/flower.jpg\") as jpeg:\n        jpeg.save(outfile, save_all=True, append_images=[jpeg.copy()])\n\n    assert os.path.isfile(outfile)\n    assert os.path.getsize(outfile) > 0\n\n\ndef test_multiframe_normal_save(tmp_path):\n    # Test saving a multiframe image without save_all\n    with Image.open(\"Tests/images/dispose_bgnd.gif\") as im:\n        outfile = str(tmp_path / \"temp.pdf\")\n        im.save(outfile)\n\n    assert os.path.isfile(outfile)\n    assert os.path.getsize(outfile) > 0\n\n\ndef test_pdf_open(tmp_path):\n    # fail on a buffer full of null bytes\n    with pytest.raises(PdfParser.PdfFormatError):\n        PdfParser.PdfParser(buf=bytearray(65536))\n\n    # make an empty PDF object\n    with PdfParser.PdfParser() as empty_pdf:\n        assert len(empty_pdf.pages) == 0\n        assert len(empty_pdf.info) == 0\n        assert not empty_pdf.should_close_buf\n        assert not empty_pdf.should_close_file\n\n    # make a PDF file\n    pdf_filename = helper_save_as_pdf(tmp_path, \"RGB\")\n\n    # open the PDF file\n    with PdfParser.PdfParser(filename=pdf_filename) as hopper_pdf:\n        assert len(hopper_pdf.pages) == 1\n        assert hopper_pdf.should_close_buf\n        assert hopper_pdf.should_close_file\n\n    # read a PDF file from a buffer with a non-zero offset\n    with open(pdf_filename, \"rb\") as f:\n        content = b\"xyzzy\" + f.read()\n    with PdfParser.PdfParser(buf=content, start_offset=5) as hopper_pdf:\n        assert len(hopper_pdf.pages) == 1\n        assert not hopper_pdf.should_close_buf\n        assert not hopper_pdf.should_close_file\n\n    # read a PDF file from an already open file\n    with open(pdf_filename, \"rb\") as f:\n        with PdfParser.PdfParser(f=f) as hopper_pdf:\n            assert len(hopper_pdf.pages) == 1\n            assert hopper_pdf.should_close_buf\n            assert not hopper_pdf.should_close_file\n\n\ndef test_pdf_append_fails_on_nonexistent_file():\n    im = hopper(\"RGB\")\n    with tempfile.TemporaryDirectory() as temp_dir:\n        with pytest.raises(OSError):\n            im.save(os.path.join(temp_dir, \"nonexistent.pdf\"), append=True)\n\n\ndef check_pdf_pages_consistency(pdf):\n    pages_info = pdf.read_indirect(pdf.pages_ref)\n    assert b\"Parent\" not in pages_info\n    assert b\"Kids\" in pages_info\n    kids_not_used = pages_info[b\"Kids\"]\n    for page_ref in pdf.pages:\n        while True:\n            if page_ref in kids_not_used:\n                kids_not_used.remove(page_ref)\n            page_info = pdf.read_indirect(page_ref)\n            assert b\"Parent\" in page_info\n            page_ref = page_info[b\"Parent\"]\n            if page_ref == pdf.pages_ref:\n                break\n        assert pdf.pages_ref == page_info[b\"Parent\"]\n    assert kids_not_used == []\n\n\ndef test_pdf_append(tmp_path):\n    # make a PDF file\n    pdf_filename = helper_save_as_pdf(tmp_path, \"RGB\", producer=\"PdfParser\")\n\n    # open it, check pages and info\n    with PdfParser.PdfParser(pdf_filename, mode=\"r+b\") as pdf:\n        assert len(pdf.pages) == 1\n        assert len(pdf.info) == 4\n        assert pdf.info.Title == os.path.splitext(os.path.basename(pdf_filename))[0]\n        assert pdf.info.Producer == \"PdfParser\"\n        assert b\"CreationDate\" in pdf.info\n        assert b\"ModDate\" in pdf.info\n        check_pdf_pages_consistency(pdf)\n\n        # append some info\n        pdf.info.Title = \"abc\"\n        pdf.info.Author = \"def\"\n        pdf.info.Subject = \"ghi\\uABCD\"\n        pdf.info.Keywords = \"qw)e\\\\r(ty\"\n        pdf.info.Creator = \"hopper()\"\n        pdf.start_writing()\n        pdf.write_xref_and_trailer()\n\n    # open it again, check pages and info again\n    with PdfParser.PdfParser(pdf_filename) as pdf:\n        assert len(pdf.pages) == 1\n        assert len(pdf.info) == 8\n        assert pdf.info.Title == \"abc\"\n        assert b\"CreationDate\" in pdf.info\n        assert b\"ModDate\" in pdf.info\n        check_pdf_pages_consistency(pdf)\n\n    # append two images\n    mode_cmyk = hopper(\"CMYK\")\n    mode_p = hopper(\"P\")\n    mode_cmyk.save(pdf_filename, append=True, save_all=True, append_images=[mode_p])\n\n    # open the PDF again, check pages and info again\n    with PdfParser.PdfParser(pdf_filename) as pdf:\n        assert len(pdf.pages) == 3\n        assert len(pdf.info) == 8\n        assert PdfParser.decode_text(pdf.info[b\"Title\"]) == \"abc\"\n        assert pdf.info.Title == \"abc\"\n        assert pdf.info.Producer == \"PdfParser\"\n        assert pdf.info.Keywords == \"qw)e\\\\r(ty\"\n        assert pdf.info.Subject == \"ghi\\uABCD\"\n        assert b\"CreationDate\" in pdf.info\n        assert b\"ModDate\" in pdf.info\n        check_pdf_pages_consistency(pdf)\n\n\ndef test_pdf_info(tmp_path):\n    # make a PDF file\n    pdf_filename = helper_save_as_pdf(\n        tmp_path,\n        \"RGB\",\n        title=\"title\",\n        author=\"author\",\n        subject=\"subject\",\n        keywords=\"keywords\",\n        creator=\"creator\",\n        producer=\"producer\",\n        creationDate=time.strptime(\"2000\", \"%Y\"),\n        modDate=time.strptime(\"2001\", \"%Y\"),\n    )\n\n    # open it, check pages and info\n    with PdfParser.PdfParser(pdf_filename) as pdf:\n        assert len(pdf.info) == 8\n        assert pdf.info.Title == \"title\"\n        assert pdf.info.Author == \"author\"\n        assert pdf.info.Subject == \"subject\"\n        assert pdf.info.Keywords == \"keywords\"\n        assert pdf.info.Creator == \"creator\"\n        assert pdf.info.Producer == \"producer\"\n        assert pdf.info.CreationDate == time.strptime(\"2000\", \"%Y\")\n        assert pdf.info.ModDate == time.strptime(\"2001\", \"%Y\")\n        check_pdf_pages_consistency(pdf)\n\n\ndef test_pdf_append_to_bytesio():\n    im = hopper(\"RGB\")\n    f = io.BytesIO()\n    im.save(f, format=\"PDF\")\n    initial_size = len(f.getvalue())\n    assert initial_size > 0\n    im = hopper(\"P\")\n    f = io.BytesIO(f.getvalue())\n    im.save(f, format=\"PDF\", append=True)\n    assert len(f.getvalue()) > initial_size\n\n\n@pytest.mark.timeout(1)\n@pytest.mark.skipif(\"PILLOW_VALGRIND_TEST\" in os.environ, reason=\"Valgrind is slower\")\n@pytest.mark.parametrize(\"newline\", (b\"\\r\", b\"\\n\"))\ndef test_redos(newline):\n    malicious = b\" trailer<<>>\" + newline * 3456\n\n    # This particular exception isn't relevant here.\n    # The important thing is it doesn't timeout, cause a ReDoS (CVE-2021-25292).\n    with pytest.raises(PdfParser.PdfFormatError):\n        PdfParser.PdfParser(buf=malicious)\n",
            "new_file_content": "import io\nimport os\nimport os.path\nimport tempfile\nimport time\n\nimport pytest\n\nfrom PIL import Image, PdfParser, features\n\nfrom .helper import hopper, mark_if_feature_version, skip_unless_feature\n\n\ndef helper_save_as_pdf(tmp_path, mode, **kwargs):\n    # Arrange\n    im = hopper(mode)\n    outfile = str(tmp_path / (\"temp_\" + mode + \".pdf\"))\n\n    # Act\n    im.save(outfile, **kwargs)\n\n    # Assert\n    assert os.path.isfile(outfile)\n    assert os.path.getsize(outfile) > 0\n    with PdfParser.PdfParser(outfile) as pdf:\n        if kwargs.get(\"append_images\", False) or kwargs.get(\"append\", False):\n            assert len(pdf.pages) > 1\n        else:\n            assert len(pdf.pages) > 0\n    with open(outfile, \"rb\") as fp:\n        contents = fp.read()\n    size = tuple(\n        float(d) for d in contents.split(b\"/MediaBox [ 0 0 \")[1].split(b\"]\")[0].split()\n    )\n    assert im.size == size\n\n    return outfile\n\n\n@pytest.mark.parametrize(\"mode\", (\"L\", \"P\", \"RGB\", \"CMYK\"))\ndef test_save(tmp_path, mode):\n    helper_save_as_pdf(tmp_path, mode)\n\n\n@skip_unless_feature(\"jpg_2000\")\n@pytest.mark.parametrize(\"mode\", (\"LA\", \"RGBA\"))\ndef test_save_alpha(tmp_path, mode):\n    helper_save_as_pdf(tmp_path, mode)\n\n\ndef test_p_alpha(tmp_path):\n    # Arrange\n    outfile = str(tmp_path / \"temp.pdf\")\n    with Image.open(\"Tests/images/pil123p.png\") as im:\n        assert im.mode == \"P\"\n        assert isinstance(im.info[\"transparency\"], bytes)\n\n        # Act\n        im.save(outfile)\n\n    # Assert\n    with open(outfile, \"rb\") as fp:\n        contents = fp.read()\n    assert b\"SMask\" in contents\n\n\ndef test_monochrome(tmp_path):\n    # Arrange\n    mode = \"1\"\n\n    # Act / Assert\n    outfile = helper_save_as_pdf(tmp_path, mode)\n    assert os.path.getsize(outfile) < (5000 if features.check(\"libtiff\") else 15000)\n\n\ndef test_unsupported_mode(tmp_path):\n    im = hopper(\"PA\")\n    outfile = str(tmp_path / \"temp_PA.pdf\")\n\n    with pytest.raises(ValueError):\n        im.save(outfile)\n\n\ndef test_resolution(tmp_path):\n    im = hopper()\n\n    outfile = str(tmp_path / \"temp.pdf\")\n    im.save(outfile, resolution=150)\n\n    with open(outfile, \"rb\") as fp:\n        contents = fp.read()\n\n    size = tuple(\n        float(d)\n        for d in contents.split(b\"stream\\nq \")[1].split(b\" 0 0 cm\")[0].split(b\" 0 0 \")\n    )\n    assert size == (61.44, 61.44)\n\n    size = tuple(\n        float(d) for d in contents.split(b\"/MediaBox [ 0 0 \")[1].split(b\"]\")[0].split()\n    )\n    assert size == (61.44, 61.44)\n\n\n@pytest.mark.parametrize(\n    \"params\",\n    (\n        {\"dpi\": (75, 150)},\n        {\"dpi\": (75, 150), \"resolution\": 200},\n    ),\n)\ndef test_dpi(params, tmp_path):\n    im = hopper()\n\n    outfile = str(tmp_path / \"temp.pdf\")\n    im.save(outfile, **params)\n\n    with open(outfile, \"rb\") as fp:\n        contents = fp.read()\n\n    size = tuple(\n        float(d)\n        for d in contents.split(b\"stream\\nq \")[1].split(b\" 0 0 cm\")[0].split(b\" 0 0 \")\n    )\n    assert size == (122.88, 61.44)\n\n    size = tuple(\n        float(d) for d in contents.split(b\"/MediaBox [ 0 0 \")[1].split(b\"]\")[0].split()\n    )\n    assert size == (122.88, 61.44)\n\n\n@mark_if_feature_version(\n    pytest.mark.valgrind_known_error, \"libjpeg_turbo\", \"2.0\", reason=\"Known Failing\"\n)\ndef test_save_all(tmp_path):\n    # Single frame image\n    helper_save_as_pdf(tmp_path, \"RGB\", save_all=True)\n\n    # Multiframe image\n    with Image.open(\"Tests/images/dispose_bgnd.gif\") as im:\n        outfile = str(tmp_path / \"temp.pdf\")\n        im.save(outfile, save_all=True)\n\n        assert os.path.isfile(outfile)\n        assert os.path.getsize(outfile) > 0\n\n        # Append images\n        ims = [hopper()]\n        im.copy().save(outfile, save_all=True, append_images=ims)\n\n        assert os.path.isfile(outfile)\n        assert os.path.getsize(outfile) > 0\n\n        # Test appending using a generator\n        def im_generator(ims):\n            yield from ims\n\n        im.save(outfile, save_all=True, append_images=im_generator(ims))\n\n    assert os.path.isfile(outfile)\n    assert os.path.getsize(outfile) > 0\n\n    # Append JPEG images\n    with Image.open(\"Tests/images/flower.jpg\") as jpeg:\n        jpeg.save(outfile, save_all=True, append_images=[jpeg.copy()])\n\n    assert os.path.isfile(outfile)\n    assert os.path.getsize(outfile) > 0\n\n\ndef test_multiframe_normal_save(tmp_path):\n    # Test saving a multiframe image without save_all\n    with Image.open(\"Tests/images/dispose_bgnd.gif\") as im:\n        outfile = str(tmp_path / \"temp.pdf\")\n        im.save(outfile)\n\n    assert os.path.isfile(outfile)\n    assert os.path.getsize(outfile) > 0\n\n\ndef test_pdf_open(tmp_path):\n    # fail on a buffer full of null bytes\n    with pytest.raises(PdfParser.PdfFormatError):\n        PdfParser.PdfParser(buf=bytearray(65536))\n\n    # make an empty PDF object\n    with PdfParser.PdfParser() as empty_pdf:\n        assert len(empty_pdf.pages) == 0\n        assert len(empty_pdf.info) == 0\n        assert not empty_pdf.should_close_buf\n        assert not empty_pdf.should_close_file\n\n    # make a PDF file\n    pdf_filename = helper_save_as_pdf(tmp_path, \"RGB\")\n\n    # open the PDF file\n    with PdfParser.PdfParser(filename=pdf_filename) as hopper_pdf:\n        assert len(hopper_pdf.pages) == 1\n        assert hopper_pdf.should_close_buf\n        assert hopper_pdf.should_close_file\n\n    # read a PDF file from a buffer with a non-zero offset\n    with open(pdf_filename, \"rb\") as f:\n        content = b\"xyzzy\" + f.read()\n    with PdfParser.PdfParser(buf=content, start_offset=5) as hopper_pdf:\n        assert len(hopper_pdf.pages) == 1\n        assert not hopper_pdf.should_close_buf\n        assert not hopper_pdf.should_close_file\n\n    # read a PDF file from an already open file\n    with open(pdf_filename, \"rb\") as f:\n        with PdfParser.PdfParser(f=f) as hopper_pdf:\n            assert len(hopper_pdf.pages) == 1\n            assert hopper_pdf.should_close_buf\n            assert not hopper_pdf.should_close_file\n\n\ndef test_pdf_append_fails_on_nonexistent_file():\n    im = hopper(\"RGB\")\n    with tempfile.TemporaryDirectory() as temp_dir:\n        with pytest.raises(OSError):\n            im.save(os.path.join(temp_dir, \"nonexistent.pdf\"), append=True)\n\n\ndef check_pdf_pages_consistency(pdf):\n    pages_info = pdf.read_indirect(pdf.pages_ref)\n    assert b\"Parent\" not in pages_info\n    assert b\"Kids\" in pages_info\n    kids_not_used = pages_info[b\"Kids\"]\n    for page_ref in pdf.pages:\n        while True:\n            if page_ref in kids_not_used:\n                kids_not_used.remove(page_ref)\n            page_info = pdf.read_indirect(page_ref)\n            assert b\"Parent\" in page_info\n            page_ref = page_info[b\"Parent\"]\n            if page_ref == pdf.pages_ref:\n                break\n        assert pdf.pages_ref == page_info[b\"Parent\"]\n    assert kids_not_used == []\n\n\ndef test_pdf_append(tmp_path):\n    # make a PDF file\n    pdf_filename = helper_save_as_pdf(tmp_path, \"RGB\", producer=\"PdfParser\")\n\n    # open it, check pages and info\n    with PdfParser.PdfParser(pdf_filename, mode=\"r+b\") as pdf:\n        assert len(pdf.pages) == 1\n        assert len(pdf.info) == 4\n        assert pdf.info.Title == os.path.splitext(os.path.basename(pdf_filename))[0]\n        assert pdf.info.Producer == \"PdfParser\"\n        assert b\"CreationDate\" in pdf.info\n        assert b\"ModDate\" in pdf.info\n        check_pdf_pages_consistency(pdf)\n\n        # append some info\n        pdf.info.Title = \"abc\"\n        pdf.info.Author = \"def\"\n        pdf.info.Subject = \"ghi\\uABCD\"\n        pdf.info.Keywords = \"qw)e\\\\r(ty\"\n        pdf.info.Creator = \"hopper()\"\n        pdf.start_writing()\n        pdf.write_xref_and_trailer()\n\n    # open it again, check pages and info again\n    with PdfParser.PdfParser(pdf_filename) as pdf:\n        assert len(pdf.pages) == 1\n        assert len(pdf.info) == 8\n        assert pdf.info.Title == \"abc\"\n        assert b\"CreationDate\" in pdf.info\n        assert b\"ModDate\" in pdf.info\n        check_pdf_pages_consistency(pdf)\n\n    # append two images\n    mode_cmyk = hopper(\"CMYK\")\n    mode_p = hopper(\"P\")\n    mode_cmyk.save(pdf_filename, append=True, save_all=True, append_images=[mode_p])\n\n    # open the PDF again, check pages and info again\n    with PdfParser.PdfParser(pdf_filename) as pdf:\n        assert len(pdf.pages) == 3\n        assert len(pdf.info) == 8\n        assert PdfParser.decode_text(pdf.info[b\"Title\"]) == \"abc\"\n        assert pdf.info.Title == \"abc\"\n        assert pdf.info.Producer == \"PdfParser\"\n        assert pdf.info.Keywords == \"qw)e\\\\r(ty\"\n        assert pdf.info.Subject == \"ghi\\uABCD\"\n        assert b\"CreationDate\" in pdf.info\n        assert b\"ModDate\" in pdf.info\n        check_pdf_pages_consistency(pdf)\n\n\ndef test_pdf_info(tmp_path):\n    # make a PDF file\n    pdf_filename = helper_save_as_pdf(\n        tmp_path,\n        \"RGB\",\n        title=\"title\",\n        author=\"author\",\n        subject=\"subject\",\n        keywords=\"keywords\",\n        creator=\"creator\",\n        producer=\"producer\",\n        creationDate=time.strptime(\"2000\", \"%Y\"),\n        modDate=time.strptime(\"2001\", \"%Y\"),\n    )\n\n    # open it, check pages and info\n    with PdfParser.PdfParser(pdf_filename) as pdf:\n        assert len(pdf.info) == 8\n        assert pdf.info.Title == \"title\"\n        assert pdf.info.Author == \"author\"\n        assert pdf.info.Subject == \"subject\"\n        assert pdf.info.Keywords == \"keywords\"\n        assert pdf.info.Creator == \"creator\"\n        assert pdf.info.Producer == \"producer\"\n        assert pdf.info.CreationDate == time.strptime(\"2000\", \"%Y\")\n        assert pdf.info.ModDate == time.strptime(\"2001\", \"%Y\")\n        check_pdf_pages_consistency(pdf)\n\n\ndef test_pdf_append_to_bytesio():\n    im = hopper(\"RGB\")\n    f = io.BytesIO()\n    im.save(f, format=\"PDF\")\n    initial_size = len(f.getvalue())\n    assert initial_size > 0\n    im = hopper(\"P\")\n    f = io.BytesIO(f.getvalue())\n    im.save(f, format=\"PDF\", append=True)\n    assert len(f.getvalue()) > initial_size\n\n\n@pytest.mark.timeout(1)\n@pytest.mark.skipif(\"PILLOW_VALGRIND_TEST\" in os.environ, reason=\"Valgrind is slower\")\n@pytest.mark.parametrize(\"newline\", (b\"\\r\", b\"\\n\"))\ndef test_redos(newline):\n    malicious = b\" trailer<<>>\" + newline * 3456\n\n    # This particular exception isn't relevant here.\n    # The important thing is it doesn't timeout, cause a ReDoS (CVE-2021-25292).\n    with pytest.raises(PdfParser.PdfFormatError):\n        PdfParser.PdfParser(buf=malicious)\n",
            "header": {
                "file": {
                    "path": "Tests/test_file_pdf.py"
                },
                "misc_line": null
            },
            "index_line": {
                "old_commit_hash": "9c8e90b7e",
                "new_commit_hash": "4f7b09af2",
                "mode": "100644"
            },
            "is_binary_file": false,
            "binary_line": null,
            "minus_file": {
                "path": "a/Tests/test_file_pdf.py"
            },
            "plus_file": {
                "path": "b/Tests/test_file_pdf.py"
            },
            "hunks": [
                {
                    "descriptor": {
                        "old_range": {
                            "start": 48,
                            "length": 6
                        },
                        "new_range": {
                            "start": 48,
                            "length": 22
                        },
                        "section": "def test_save_alpha(tmp_path, mode):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "    helper_save_as_pdf(tmp_path, mode)",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "def test_p_alpha(tmp_path):",
                                "type": "added"
                            },
                            {
                                "content": "    # Arrange",
                                "type": "added"
                            },
                            {
                                "content": "    outfile = str(tmp_path / \"temp.pdf\")",
                                "type": "added"
                            },
                            {
                                "content": "    with Image.open(\"Tests/images/pil123p.png\") as im:",
                                "type": "added"
                            },
                            {
                                "content": "        assert im.mode == \"P\"",
                                "type": "added"
                            },
                            {
                                "content": "        assert isinstance(im.info[\"transparency\"], bytes)",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "        # Act",
                                "type": "added"
                            },
                            {
                                "content": "        im.save(outfile)",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "    # Assert",
                                "type": "added"
                            },
                            {
                                "content": "    with open(outfile, \"rb\") as fp:",
                                "type": "added"
                            },
                            {
                                "content": "        contents = fp.read()",
                                "type": "added"
                            },
                            {
                                "content": "    assert b\"SMask\" in contents",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "def test_monochrome(tmp_path):",
                                "type": "context"
                            },
                            {
                                "content": "    # Arrange",
                                "type": "context"
                            },
                            {
                                "content": "    mode = \"1\"",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [],
                    "added_entities": [
                        {
                            "file_name": "Tests/test_file_pdf.py",
                            "type": "function",
                            "name": "test_p_alpha",
                            "content": "def test_p_alpha(tmp_path):\n    # Arrange\n    outfile = str(tmp_path / \"temp.pdf\")\n    with Image.open(\"Tests/images/pil123p.png\") as im:\n        assert im.mode == \"P\"\n        assert isinstance(im.info[\"transparency\"], bytes)\n\n        # Act\n        im.save(outfile)\n\n    # Assert\n    with open(outfile, \"rb\") as fp:\n        contents = fp.read()\n    assert b\"SMask\" in contents",
                            "ast_type_str": "FunctionDef",
                            "start_lineno": 51,
                            "end_lineno": 64,
                            "parent": null
                        }
                    ],
                    "deleted_entities": []
                }
            ]
        },
        {
            "old_file_content": "#\n# The Python Imaging Library.\n# $Id$\n#\n# PDF (Acrobat) file handling\n#\n# History:\n# 1996-07-16 fl   Created\n# 1997-01-18 fl   Fixed header\n# 2004-02-21 fl   Fixes for 1/L/CMYK images, etc.\n# 2004-02-24 fl   Fixes for 1 and P images.\n#\n# Copyright (c) 1997-2004 by Secret Labs AB.  All rights reserved.\n# Copyright (c) 1996-1997 by Fredrik Lundh.\n#\n# See the README file for information on usage and redistribution.\n#\n\n##\n# Image plugin for PDF images (output only).\n##\n\nimport io\nimport math\nimport os\nimport time\n\nfrom . import Image, ImageFile, ImageSequence, PdfParser, __version__, features\n\n#\n# --------------------------------------------------------------------\n\n# object ids:\n#  1. catalogue\n#  2. pages\n#  3. image\n#  4. page\n#  5. page contents\n\n\ndef _save_all(im, fp, filename):\n    _save(im, fp, filename, save_all=True)\n\n\n##\n# (Internal) Image save plugin for the PDF format.\n\n\ndef _write_image(im, filename, existing_pdf, image_refs):\n    # FIXME: Should replace ASCIIHexDecode with RunLengthDecode\n    # (packbits) or LZWDecode (tiff/lzw compression).  Note that\n    # PDF 1.2 also supports Flatedecode (zip compression).\n\n    params = None\n    decode = None\n\n    #\n    # Get image characteristics\n\n    width, height = im.size\n\n    dict_obj = {\"BitsPerComponent\": 8}\n    if im.mode == \"1\":\n        if features.check(\"libtiff\"):\n            filter = \"CCITTFaxDecode\"\n            dict_obj[\"BitsPerComponent\"] = 1\n            params = PdfParser.PdfArray(\n                [\n                    PdfParser.PdfDict(\n                        {\n                            \"K\": -1,\n                            \"BlackIs1\": True,\n                            \"Columns\": width,\n                            \"Rows\": height,\n                        }\n                    )\n                ]\n            )\n        else:\n            filter = \"DCTDecode\"\n        dict_obj[\"ColorSpace\"] = PdfParser.PdfName(\"DeviceGray\")\n        procset = \"ImageB\"  # grayscale\n    elif im.mode == \"L\":\n        filter = \"DCTDecode\"\n        # params = f\"<< /Predictor 15 /Columns {width-2} >>\"\n        dict_obj[\"ColorSpace\"] = PdfParser.PdfName(\"DeviceGray\")\n        procset = \"ImageB\"  # grayscale\n    elif im.mode == \"LA\":\n        filter = \"JPXDecode\"\n        # params = f\"<< /Predictor 15 /Columns {width-2} >>\"\n        procset = \"ImageB\"  # grayscale\n        dict_obj[\"SMaskInData\"] = 1\n    elif im.mode == \"P\":\n        filter = \"ASCIIHexDecode\"\n        palette = im.getpalette()\n        dict_obj[\"ColorSpace\"] = [\n            PdfParser.PdfName(\"Indexed\"),\n            PdfParser.PdfName(\"DeviceRGB\"),\n            255,\n            PdfParser.PdfBinary(palette),\n        ]\n        procset = \"ImageI\"  # indexed color\n    elif im.mode == \"RGB\":\n        filter = \"DCTDecode\"\n        dict_obj[\"ColorSpace\"] = PdfParser.PdfName(\"DeviceRGB\")\n        procset = \"ImageC\"  # color images\n    elif im.mode == \"RGBA\":\n        filter = \"JPXDecode\"\n        procset = \"ImageC\"  # color images\n        dict_obj[\"SMaskInData\"] = 1\n    elif im.mode == \"CMYK\":\n        filter = \"DCTDecode\"\n        dict_obj[\"ColorSpace\"] = PdfParser.PdfName(\"DeviceCMYK\")\n        procset = \"ImageC\"  # color images\n        decode = [1, 0, 1, 0, 1, 0, 1, 0]\n    else:\n        msg = f\"cannot save mode {im.mode}\"\n        raise ValueError(msg)\n\n    #\n    # image\n\n    op = io.BytesIO()\n\n    if filter == \"ASCIIHexDecode\":\n        ImageFile._save(im, op, [(\"hex\", (0, 0) + im.size, 0, im.mode)])\n    elif filter == \"CCITTFaxDecode\":\n        im.save(\n            op,\n            \"TIFF\",\n            compression=\"group4\",\n            # use a single strip\n            strip_size=math.ceil(im.width / 8) * im.height,\n        )\n    elif filter == \"DCTDecode\":\n        Image.SAVE[\"JPEG\"](im, op, filename)\n    elif filter == \"JPXDecode\":\n        del dict_obj[\"BitsPerComponent\"]\n        Image.SAVE[\"JPEG2000\"](im, op, filename)\n    elif filter == \"FlateDecode\":\n        ImageFile._save(im, op, [(\"zip\", (0, 0) + im.size, 0, im.mode)])\n    elif filter == \"RunLengthDecode\":\n        ImageFile._save(im, op, [(\"packbits\", (0, 0) + im.size, 0, im.mode)])\n    else:\n        msg = f\"unsupported PDF filter ({filter})\"\n        raise ValueError(msg)\n\n    stream = op.getvalue()\n    if filter == \"CCITTFaxDecode\":\n        stream = stream[8:]\n        filter = PdfParser.PdfArray([PdfParser.PdfName(filter)])\n    else:\n        filter = PdfParser.PdfName(filter)\n\n    existing_pdf.write_obj(\n        image_refs[page_number],\n        stream=stream,\n        Type=PdfParser.PdfName(\"XObject\"),\n        Subtype=PdfParser.PdfName(\"Image\"),\n        Width=width,  # * 72.0 / x_resolution,\n        Height=height,  # * 72.0 / y_resolution,\n        Filter=filter,\n        Decode=decode,\n        DecodeParms=params,\n        **dict_obj,\n    )\n\n    return procset\n\n\ndef _save(im, fp, filename, save_all=False):\n    is_appending = im.encoderinfo.get(\"append\", False)\n    if is_appending:\n        existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode=\"r+b\")\n    else:\n        existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode=\"w+b\")\n\n    dpi = im.encoderinfo.get(\"dpi\")\n    if dpi:\n        x_resolution = dpi[0]\n        y_resolution = dpi[1]\n    else:\n        x_resolution = y_resolution = im.encoderinfo.get(\"resolution\", 72.0)\n\n    info = {\n        \"title\": None\n        if is_appending\n        else os.path.splitext(os.path.basename(filename))[0],\n        \"author\": None,\n        \"subject\": None,\n        \"keywords\": None,\n        \"creator\": None,\n        \"producer\": None,\n        \"creationDate\": None if is_appending else time.gmtime(),\n        \"modDate\": None if is_appending else time.gmtime(),\n    }\n    for k, default in info.items():\n        v = im.encoderinfo.get(k) if k in im.encoderinfo else default\n        if v:\n            existing_pdf.info[k[0].upper() + k[1:]] = v\n\n    #\n    # make sure image data is available\n    im.load()\n\n    existing_pdf.start_writing()\n    existing_pdf.write_header()\n    existing_pdf.write_comment(f\"created by Pillow {__version__} PDF driver\")\n\n    #\n    # pages\n    ims = [im]\n    if save_all:\n        append_images = im.encoderinfo.get(\"append_images\", [])\n        for append_im in append_images:\n            append_im.encoderinfo = im.encoderinfo.copy()\n            ims.append(append_im)\n    number_of_pages = 0\n    image_refs = []\n    page_refs = []\n    contents_refs = []\n    for im in ims:\n        im_number_of_pages = 1\n        if save_all:\n            try:\n                im_number_of_pages = im.n_frames\n            except AttributeError:\n                # Image format does not have n_frames.\n                # It is a single frame image\n                pass\n        number_of_pages += im_number_of_pages\n        for i in range(im_number_of_pages):\n            image_refs.append(existing_pdf.next_object_id(0))\n            page_refs.append(existing_pdf.next_object_id(0))\n            contents_refs.append(existing_pdf.next_object_id(0))\n            existing_pdf.pages.append(page_refs[-1])\n\n    #\n    # catalog and list of pages\n    existing_pdf.write_catalog()\n\n    page_number = 0\n    for im_sequence in ims:\n        im_pages = ImageSequence.Iterator(im_sequence) if save_all else [im_sequence]\n        for im in im_pages:\n            procset = _write_image(im, filename, existing_pdfs, image_refs)\n\n            #\n            # page\n\n            existing_pdf.write_page(\n                page_refs[page_number],\n                Resources=PdfParser.PdfDict(\n                    ProcSet=[PdfParser.PdfName(\"PDF\"), PdfParser.PdfName(procset)],\n                    XObject=PdfParser.PdfDict(image=image_refs[page_number]),\n                ),\n                MediaBox=[\n                    0,\n                    0,\n                    im.width * 72.0 / x_resolution,\n                    im.height * 72.0 / y_resolution,\n                ],\n                Contents=contents_refs[page_number],\n            )\n\n            #\n            # page contents\n\n            page_contents = b\"q %f 0 0 %f 0 0 cm /image Do Q\\n\" % (\n                im.width * 72.0 / x_resolution,\n                im.height * 72.0 / y_resolution,\n            )\n\n            existing_pdf.write_obj(contents_refs[page_number], stream=page_contents)\n\n            page_number += 1\n\n    #\n    # trailer\n    existing_pdf.write_xref_and_trailer()\n    if hasattr(fp, \"flush\"):\n        fp.flush()\n    existing_pdf.close()\n\n\n#\n# --------------------------------------------------------------------\n\n\nImage.register_save(\"PDF\", _save)\nImage.register_save_all(\"PDF\", _save_all)\n\nImage.register_extension(\"PDF\", \".pdf\")\n\nImage.register_mime(\"PDF\", \"application/pdf\")\n",
            "new_file_content": "#\n# The Python Imaging Library.\n# $Id$\n#\n# PDF (Acrobat) file handling\n#\n# History:\n# 1996-07-16 fl   Created\n# 1997-01-18 fl   Fixed header\n# 2004-02-21 fl   Fixes for 1/L/CMYK images, etc.\n# 2004-02-24 fl   Fixes for 1 and P images.\n#\n# Copyright (c) 1997-2004 by Secret Labs AB.  All rights reserved.\n# Copyright (c) 1996-1997 by Fredrik Lundh.\n#\n# See the README file for information on usage and redistribution.\n#\n\n##\n# Image plugin for PDF images (output only).\n##\n\nimport io\nimport math\nimport os\nimport time\n\nfrom . import Image, ImageFile, ImageSequence, PdfParser, __version__, features\n\n#\n# --------------------------------------------------------------------\n\n# object ids:\n#  1. catalogue\n#  2. pages\n#  3. image\n#  4. page\n#  5. page contents\n\n\ndef _save_all(im, fp, filename):\n    _save(im, fp, filename, save_all=True)\n\n\n##\n# (Internal) Image save plugin for the PDF format.\n\n\ndef _write_image(im, filename, existing_pdf, image_refs):\n    # FIXME: Should replace ASCIIHexDecode with RunLengthDecode\n    # (packbits) or LZWDecode (tiff/lzw compression).  Note that\n    # PDF 1.2 also supports Flatedecode (zip compression).\n\n    params = None\n    decode = None\n\n    #\n    # Get image characteristics\n\n    width, height = im.size\n\n    dict_obj = {\"BitsPerComponent\": 8}\n    if im.mode == \"1\":\n        if features.check(\"libtiff\"):\n            filter = \"CCITTFaxDecode\"\n            dict_obj[\"BitsPerComponent\"] = 1\n            params = PdfParser.PdfArray(\n                [\n                    PdfParser.PdfDict(\n                        {\n                            \"K\": -1,\n                            \"BlackIs1\": True,\n                            \"Columns\": width,\n                            \"Rows\": height,\n                        }\n                    )\n                ]\n            )\n        else:\n            filter = \"DCTDecode\"\n        dict_obj[\"ColorSpace\"] = PdfParser.PdfName(\"DeviceGray\")\n        procset = \"ImageB\"  # grayscale\n    elif im.mode == \"L\":\n        filter = \"DCTDecode\"\n        # params = f\"<< /Predictor 15 /Columns {width-2} >>\"\n        dict_obj[\"ColorSpace\"] = PdfParser.PdfName(\"DeviceGray\")\n        procset = \"ImageB\"  # grayscale\n    elif im.mode == \"LA\":\n        filter = \"JPXDecode\"\n        # params = f\"<< /Predictor 15 /Columns {width-2} >>\"\n        procset = \"ImageB\"  # grayscale\n        dict_obj[\"SMaskInData\"] = 1\n    elif im.mode == \"P\":\n        filter = \"ASCIIHexDecode\"\n        palette = im.getpalette()\n        dict_obj[\"ColorSpace\"] = [\n            PdfParser.PdfName(\"Indexed\"),\n            PdfParser.PdfName(\"DeviceRGB\"),\n            255,\n            PdfParser.PdfBinary(palette),\n        ]\n        procset = \"ImageI\"  # indexed color\n\n        if \"transparency\" in im.info:\n            smask = im.convert(\"LA\").getchannel(\"A\")\n            smask.encoderinfo = {}\n\n            image_ref = _write_image(smask, filename, existing_pdf, image_refs)[0]\n            dict_obj[\"SMask\"] = image_ref\n    elif im.mode == \"RGB\":\n        filter = \"DCTDecode\"\n        dict_obj[\"ColorSpace\"] = PdfParser.PdfName(\"DeviceRGB\")\n        procset = \"ImageC\"  # color images\n    elif im.mode == \"RGBA\":\n        filter = \"JPXDecode\"\n        procset = \"ImageC\"  # color images\n        dict_obj[\"SMaskInData\"] = 1\n    elif im.mode == \"CMYK\":\n        filter = \"DCTDecode\"\n        dict_obj[\"ColorSpace\"] = PdfParser.PdfName(\"DeviceCMYK\")\n        procset = \"ImageC\"  # color images\n        decode = [1, 0, 1, 0, 1, 0, 1, 0]\n    else:\n        msg = f\"cannot save mode {im.mode}\"\n        raise ValueError(msg)\n\n    #\n    # image\n\n    op = io.BytesIO()\n\n    if filter == \"ASCIIHexDecode\":\n        ImageFile._save(im, op, [(\"hex\", (0, 0) + im.size, 0, im.mode)])\n    elif filter == \"CCITTFaxDecode\":\n        im.save(\n            op,\n            \"TIFF\",\n            compression=\"group4\",\n            # use a single strip\n            strip_size=math.ceil(width / 8) * height,\n        )\n    elif filter == \"DCTDecode\":\n        Image.SAVE[\"JPEG\"](im, op, filename)\n    elif filter == \"JPXDecode\":\n        del dict_obj[\"BitsPerComponent\"]\n        Image.SAVE[\"JPEG2000\"](im, op, filename)\n    elif filter == \"FlateDecode\":\n        ImageFile._save(im, op, [(\"zip\", (0, 0) + im.size, 0, im.mode)])\n    elif filter == \"RunLengthDecode\":\n        ImageFile._save(im, op, [(\"packbits\", (0, 0) + im.size, 0, im.mode)])\n    else:\n        msg = f\"unsupported PDF filter ({filter})\"\n        raise ValueError(msg)\n\n    stream = op.getvalue()\n    if filter == \"CCITTFaxDecode\":\n        stream = stream[8:]\n        filter = PdfParser.PdfArray([PdfParser.PdfName(filter)])\n    else:\n        filter = PdfParser.PdfName(filter)\n\n    image_ref = image_refs.pop(0)\n    existing_pdf.write_obj(\n        image_ref,\n        stream=stream,\n        Type=PdfParser.PdfName(\"XObject\"),\n        Subtype=PdfParser.PdfName(\"Image\"),\n        Width=width,  # * 72.0 / x_resolution,\n        Height=height,  # * 72.0 / y_resolution,\n        Filter=filter,\n        Decode=decode,\n        DecodeParms=params,\n        **dict_obj,\n    )\n\n    return image_ref, procset\n\n\ndef _save(im, fp, filename, save_all=False):\n    is_appending = im.encoderinfo.get(\"append\", False)\n    if is_appending:\n        existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode=\"r+b\")\n    else:\n        existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode=\"w+b\")\n\n    dpi = im.encoderinfo.get(\"dpi\")\n    if dpi:\n        x_resolution = dpi[0]\n        y_resolution = dpi[1]\n    else:\n        x_resolution = y_resolution = im.encoderinfo.get(\"resolution\", 72.0)\n\n    info = {\n        \"title\": None\n        if is_appending\n        else os.path.splitext(os.path.basename(filename))[0],\n        \"author\": None,\n        \"subject\": None,\n        \"keywords\": None,\n        \"creator\": None,\n        \"producer\": None,\n        \"creationDate\": None if is_appending else time.gmtime(),\n        \"modDate\": None if is_appending else time.gmtime(),\n    }\n    for k, default in info.items():\n        v = im.encoderinfo.get(k) if k in im.encoderinfo else default\n        if v:\n            existing_pdf.info[k[0].upper() + k[1:]] = v\n\n    #\n    # make sure image data is available\n    im.load()\n\n    existing_pdf.start_writing()\n    existing_pdf.write_header()\n    existing_pdf.write_comment(f\"created by Pillow {__version__} PDF driver\")\n\n    #\n    # pages\n    ims = [im]\n    if save_all:\n        append_images = im.encoderinfo.get(\"append_images\", [])\n        for append_im in append_images:\n            append_im.encoderinfo = im.encoderinfo.copy()\n            ims.append(append_im)\n    number_of_pages = 0\n    image_refs = []\n    page_refs = []\n    contents_refs = []\n    for im in ims:\n        im_number_of_pages = 1\n        if save_all:\n            try:\n                im_number_of_pages = im.n_frames\n            except AttributeError:\n                # Image format does not have n_frames.\n                # It is a single frame image\n                pass\n        number_of_pages += im_number_of_pages\n        for i in range(im_number_of_pages):\n            image_refs.append(existing_pdf.next_object_id(0))\n            if im.mode == \"P\" and \"transparency\" in im.info:\n                image_refs.append(existing_pdf.next_object_id(0))\n\n            page_refs.append(existing_pdf.next_object_id(0))\n            contents_refs.append(existing_pdf.next_object_id(0))\n            existing_pdf.pages.append(page_refs[-1])\n\n    #\n    # catalog and list of pages\n    existing_pdf.write_catalog()\n\n    page_number = 0\n    for im_sequence in ims:\n        im_pages = ImageSequence.Iterator(im_sequence) if save_all else [im_sequence]\n        for im in im_pages:\n            image_ref, procset = _write_image(im, filename, existing_pdf, image_refs)\n\n            #\n            # page\n\n            existing_pdf.write_page(\n                page_refs[page_number],\n                Resources=PdfParser.PdfDict(\n                    ProcSet=[PdfParser.PdfName(\"PDF\"), PdfParser.PdfName(procset)],\n                    XObject=PdfParser.PdfDict(image=image_ref),\n                ),\n                MediaBox=[\n                    0,\n                    0,\n                    im.width * 72.0 / x_resolution,\n                    im.height * 72.0 / y_resolution,\n                ],\n                Contents=contents_refs[page_number],\n            )\n\n            #\n            # page contents\n\n            page_contents = b\"q %f 0 0 %f 0 0 cm /image Do Q\\n\" % (\n                im.width * 72.0 / x_resolution,\n                im.height * 72.0 / y_resolution,\n            )\n\n            existing_pdf.write_obj(contents_refs[page_number], stream=page_contents)\n\n            page_number += 1\n\n    #\n    # trailer\n    existing_pdf.write_xref_and_trailer()\n    if hasattr(fp, \"flush\"):\n        fp.flush()\n    existing_pdf.close()\n\n\n#\n# --------------------------------------------------------------------\n\n\nImage.register_save(\"PDF\", _save)\nImage.register_save_all(\"PDF\", _save_all)\n\nImage.register_extension(\"PDF\", \".pdf\")\n\nImage.register_mime(\"PDF\", \"application/pdf\")\n",
            "header": {
                "file": {
                    "path": "src/PIL/PdfImagePlugin.py"
                },
                "misc_line": null
            },
            "index_line": {
                "old_commit_hash": "be39f4d16",
                "new_commit_hash": "e3af1b452",
                "mode": "100644"
            },
            "is_binary_file": false,
            "binary_line": null,
            "minus_file": {
                "path": "a/src/PIL/PdfImagePlugin.py"
            },
            "plus_file": {
                "path": "b/src/PIL/PdfImagePlugin.py"
            },
            "hunks": [
                {
                    "descriptor": {
                        "old_range": {
                            "start": 100,
                            "length": 6
                        },
                        "new_range": {
                            "start": 100,
                            "length": 13
                        },
                        "section": "def _write_image(im, filename, existing_pdf, image_refs):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "            PdfParser.PdfBinary(palette),",
                                "type": "context"
                            },
                            {
                                "content": "        ]",
                                "type": "context"
                            },
                            {
                                "content": "        procset = \"ImageI\"  # indexed color",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "        if \"transparency\" in im.info:",
                                "type": "added"
                            },
                            {
                                "content": "            smask = im.convert(\"LA\").getchannel(\"A\")",
                                "type": "added"
                            },
                            {
                                "content": "            smask.encoderinfo = {}",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "            image_ref = _write_image(smask, filename, existing_pdf, image_refs)[0]",
                                "type": "added"
                            },
                            {
                                "content": "            dict_obj[\"SMask\"] = image_ref",
                                "type": "added"
                            },
                            {
                                "content": "    elif im.mode == \"RGB\":",
                                "type": "context"
                            },
                            {
                                "content": "        filter = \"DCTDecode\"",
                                "type": "context"
                            },
                            {
                                "content": "        dict_obj[\"ColorSpace\"] = PdfParser.PdfName(\"DeviceRGB\")",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "src/PIL/PdfImagePlugin.py",
                            "type": "function",
                            "name": "_write_image",
                            "content": "def _write_image(im, filename, existing_pdf, image_refs):\n    # FIXME: Should replace ASCIIHexDecode with RunLengthDecode\n    # (packbits) or LZWDecode (tiff/lzw compression).  Note that\n    # PDF 1.2 also supports Flatedecode (zip compression).\n\n    params = None\n    decode = None\n\n    #\n    # Get image characteristics\n\n    width, height = im.size\n\n    dict_obj = {\"BitsPerComponent\": 8}\n    if im.mode == \"1\":\n        if features.check(\"libtiff\"):\n            filter = \"CCITTFaxDecode\"\n            dict_obj[\"BitsPerComponent\"] = 1\n            params = PdfParser.PdfArray(\n                [\n                    PdfParser.PdfDict(\n                        {\n                            \"K\": -1,\n                            \"BlackIs1\": True,\n                            \"Columns\": width,\n                            \"Rows\": height,\n                        }\n                    )\n                ]\n            )\n        else:\n            filter = \"DCTDecode\"\n        dict_obj[\"ColorSpace\"] = PdfParser.PdfName(\"DeviceGray\")\n        procset = \"ImageB\"  # grayscale\n    elif im.mode == \"L\":\n        filter = \"DCTDecode\"\n        # params = f\"<< /Predictor 15 /Columns {width-2} >>\"\n        dict_obj[\"ColorSpace\"] = PdfParser.PdfName(\"DeviceGray\")\n        procset = \"ImageB\"  # grayscale\n    elif im.mode == \"LA\":\n        filter = \"JPXDecode\"\n        # params = f\"<< /Predictor 15 /Columns {width-2} >>\"\n        procset = \"ImageB\"  # grayscale\n        dict_obj[\"SMaskInData\"] = 1\n    elif im.mode == \"P\":\n        filter = \"ASCIIHexDecode\"\n        palette = im.getpalette()\n        dict_obj[\"ColorSpace\"] = [\n            PdfParser.PdfName(\"Indexed\"),\n            PdfParser.PdfName(\"DeviceRGB\"),\n            255,\n            PdfParser.PdfBinary(palette),\n        ]\n        procset = \"ImageI\"  # indexed color\n\n        if \"transparency\" in im.info:\n            smask = im.convert(\"LA\").getchannel(\"A\")\n            smask.encoderinfo = {}\n\n            image_ref = _write_image(smask, filename, existing_pdf, image_refs)[0]\n            dict_obj[\"SMask\"] = image_ref\n    elif im.mode == \"RGB\":\n        filter = \"DCTDecode\"\n        dict_obj[\"ColorSpace\"] = PdfParser.PdfName(\"DeviceRGB\")\n        procset = \"ImageC\"  # color images\n    elif im.mode == \"RGBA\":\n        filter = \"JPXDecode\"\n        procset = \"ImageC\"  # color images\n        dict_obj[\"SMaskInData\"] = 1\n    elif im.mode == \"CMYK\":\n        filter = \"DCTDecode\"\n        dict_obj[\"ColorSpace\"] = PdfParser.PdfName(\"DeviceCMYK\")\n        procset = \"ImageC\"  # color images\n        decode = [1, 0, 1, 0, 1, 0, 1, 0]\n    else:\n        msg = f\"cannot save mode {im.mode}\"\n        raise ValueError(msg)\n\n    #\n    # image\n\n    op = io.BytesIO()\n\n    if filter == \"ASCIIHexDecode\":\n        ImageFile._save(im, op, [(\"hex\", (0, 0) + im.size, 0, im.mode)])\n    elif filter == \"CCITTFaxDecode\":\n        im.save(\n            op,\n            \"TIFF\",\n            compression=\"group4\",\n            # use a single strip\n            strip_size=math.ceil(width / 8) * height,\n        )\n    elif filter == \"DCTDecode\":\n        Image.SAVE[\"JPEG\"](im, op, filename)\n    elif filter == \"JPXDecode\":\n        del dict_obj[\"BitsPerComponent\"]\n        Image.SAVE[\"JPEG2000\"](im, op, filename)\n    elif filter == \"FlateDecode\":\n        ImageFile._save(im, op, [(\"zip\", (0, 0) + im.size, 0, im.mode)])\n    elif filter == \"RunLengthDecode\":\n        ImageFile._save(im, op, [(\"packbits\", (0, 0) + im.size, 0, im.mode)])\n    else:\n        msg = f\"unsupported PDF filter ({filter})\"\n        raise ValueError(msg)\n\n    stream = op.getvalue()\n    if filter == \"CCITTFaxDecode\":\n        stream = stream[8:]\n        filter = PdfParser.PdfArray([PdfParser.PdfName(filter)])\n    else:\n        filter = PdfParser.PdfName(filter)\n\n    image_ref = image_refs.pop(0)\n    existing_pdf.write_obj(\n        image_ref,\n        stream=stream,\n        Type=PdfParser.PdfName(\"XObject\"),\n        Subtype=PdfParser.PdfName(\"Image\"),\n        Width=width,  # * 72.0 / x_resolution,\n        Height=height,  # * 72.0 / y_resolution,\n        Filter=filter,\n        Decode=decode,\n        DecodeParms=params,\n        **dict_obj,\n    )\n\n    return image_ref, procset",
                            "ast_type_str": "FunctionDef",
                            "start_lineno": 49,
                            "end_lineno": 176,
                            "parent": null
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                },
                {
                    "descriptor": {
                        "old_range": {
                            "start": 130,
                            "length": 7
                        },
                        "new_range": {
                            "start": 137,
                            "length": 7
                        },
                        "section": "def _write_image(im, filename, existing_pdf, image_refs):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "            \"TIFF\",",
                                "type": "context"
                            },
                            {
                                "content": "            compression=\"group4\",",
                                "type": "context"
                            },
                            {
                                "content": "            # use a single strip",
                                "type": "context"
                            },
                            {
                                "content": "            strip_size=math.ceil(im.width / 8) * im.height,",
                                "type": "deleted"
                            },
                            {
                                "content": "            strip_size=math.ceil(width / 8) * height,",
                                "type": "added"
                            },
                            {
                                "content": "        )",
                                "type": "context"
                            },
                            {
                                "content": "    elif filter == \"DCTDecode\":",
                                "type": "context"
                            },
                            {
                                "content": "        Image.SAVE[\"JPEG\"](im, op, filename)",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "src/PIL/PdfImagePlugin.py",
                            "type": "function",
                            "name": "_write_image",
                            "content": "def _write_image(im, filename, existing_pdf, image_refs):\n    # FIXME: Should replace ASCIIHexDecode with RunLengthDecode\n    # (packbits) or LZWDecode (tiff/lzw compression).  Note that\n    # PDF 1.2 also supports Flatedecode (zip compression).\n\n    params = None\n    decode = None\n\n    #\n    # Get image characteristics\n\n    width, height = im.size\n\n    dict_obj = {\"BitsPerComponent\": 8}\n    if im.mode == \"1\":\n        if features.check(\"libtiff\"):\n            filter = \"CCITTFaxDecode\"\n            dict_obj[\"BitsPerComponent\"] = 1\n            params = PdfParser.PdfArray(\n                [\n                    PdfParser.PdfDict(\n                        {\n                            \"K\": -1,\n                            \"BlackIs1\": True,\n                            \"Columns\": width,\n                            \"Rows\": height,\n                        }\n                    )\n                ]\n            )\n        else:\n            filter = \"DCTDecode\"\n        dict_obj[\"ColorSpace\"] = PdfParser.PdfName(\"DeviceGray\")\n        procset = \"ImageB\"  # grayscale\n    elif im.mode == \"L\":\n        filter = \"DCTDecode\"\n        # params = f\"<< /Predictor 15 /Columns {width-2} >>\"\n        dict_obj[\"ColorSpace\"] = PdfParser.PdfName(\"DeviceGray\")\n        procset = \"ImageB\"  # grayscale\n    elif im.mode == \"LA\":\n        filter = \"JPXDecode\"\n        # params = f\"<< /Predictor 15 /Columns {width-2} >>\"\n        procset = \"ImageB\"  # grayscale\n        dict_obj[\"SMaskInData\"] = 1\n    elif im.mode == \"P\":\n        filter = \"ASCIIHexDecode\"\n        palette = im.getpalette()\n        dict_obj[\"ColorSpace\"] = [\n            PdfParser.PdfName(\"Indexed\"),\n            PdfParser.PdfName(\"DeviceRGB\"),\n            255,\n            PdfParser.PdfBinary(palette),\n        ]\n        procset = \"ImageI\"  # indexed color\n    elif im.mode == \"RGB\":\n        filter = \"DCTDecode\"\n        dict_obj[\"ColorSpace\"] = PdfParser.PdfName(\"DeviceRGB\")\n        procset = \"ImageC\"  # color images\n    elif im.mode == \"RGBA\":\n        filter = \"JPXDecode\"\n        procset = \"ImageC\"  # color images\n        dict_obj[\"SMaskInData\"] = 1\n    elif im.mode == \"CMYK\":\n        filter = \"DCTDecode\"\n        dict_obj[\"ColorSpace\"] = PdfParser.PdfName(\"DeviceCMYK\")\n        procset = \"ImageC\"  # color images\n        decode = [1, 0, 1, 0, 1, 0, 1, 0]\n    else:\n        msg = f\"cannot save mode {im.mode}\"\n        raise ValueError(msg)\n\n    #\n    # image\n\n    op = io.BytesIO()\n\n    if filter == \"ASCIIHexDecode\":\n        ImageFile._save(im, op, [(\"hex\", (0, 0) + im.size, 0, im.mode)])\n    elif filter == \"CCITTFaxDecode\":\n        im.save(\n            op,\n            \"TIFF\",\n            compression=\"group4\",\n            # use a single strip\n            strip_size=math.ceil(im.width / 8) * im.height,\n        )\n    elif filter == \"DCTDecode\":\n        Image.SAVE[\"JPEG\"](im, op, filename)\n    elif filter == \"JPXDecode\":\n        del dict_obj[\"BitsPerComponent\"]\n        Image.SAVE[\"JPEG2000\"](im, op, filename)\n    elif filter == \"FlateDecode\":\n        ImageFile._save(im, op, [(\"zip\", (0, 0) + im.size, 0, im.mode)])\n    elif filter == \"RunLengthDecode\":\n        ImageFile._save(im, op, [(\"packbits\", (0, 0) + im.size, 0, im.mode)])\n    else:\n        msg = f\"unsupported PDF filter ({filter})\"\n        raise ValueError(msg)\n\n    stream = op.getvalue()\n    if filter == \"CCITTFaxDecode\":\n        stream = stream[8:]\n        filter = PdfParser.PdfArray([PdfParser.PdfName(filter)])\n    else:\n        filter = PdfParser.PdfName(filter)\n\n    existing_pdf.write_obj(\n        image_refs[page_number],\n        stream=stream,\n        Type=PdfParser.PdfName(\"XObject\"),\n        Subtype=PdfParser.PdfName(\"Image\"),\n        Width=width,  # * 72.0 / x_resolution,\n        Height=height,  # * 72.0 / y_resolution,\n        Filter=filter,\n        Decode=decode,\n        DecodeParms=params,\n        **dict_obj,\n    )\n\n    return procset",
                            "ast_type_str": "FunctionDef",
                            "start_lineno": 49,
                            "end_lineno": 168,
                            "parent": null
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                },
                {
                    "descriptor": {
                        "old_range": {
                            "start": 152,
                            "length": 8
                        },
                        "new_range": {
                            "start": 159,
                            "length": 9
                        },
                        "section": "def _write_image(im, filename, existing_pdf, image_refs):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "    else:",
                                "type": "context"
                            },
                            {
                                "content": "        filter = PdfParser.PdfName(filter)",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "    image_ref = image_refs.pop(0)",
                                "type": "added"
                            },
                            {
                                "content": "    existing_pdf.write_obj(",
                                "type": "context"
                            },
                            {
                                "content": "        image_refs[page_number],",
                                "type": "deleted"
                            },
                            {
                                "content": "        image_ref,",
                                "type": "added"
                            },
                            {
                                "content": "        stream=stream,",
                                "type": "context"
                            },
                            {
                                "content": "        Type=PdfParser.PdfName(\"XObject\"),",
                                "type": "context"
                            },
                            {
                                "content": "        Subtype=PdfParser.PdfName(\"Image\"),",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "src/PIL/PdfImagePlugin.py",
                            "type": "function",
                            "name": "_write_image",
                            "content": "def _write_image(im, filename, existing_pdf, image_refs):\n    # FIXME: Should replace ASCIIHexDecode with RunLengthDecode\n    # (packbits) or LZWDecode (tiff/lzw compression).  Note that\n    # PDF 1.2 also supports Flatedecode (zip compression).\n\n    params = None\n    decode = None\n\n    #\n    # Get image characteristics\n\n    width, height = im.size\n\n    dict_obj = {\"BitsPerComponent\": 8}\n    if im.mode == \"1\":\n        if features.check(\"libtiff\"):\n            filter = \"CCITTFaxDecode\"\n            dict_obj[\"BitsPerComponent\"] = 1\n            params = PdfParser.PdfArray(\n                [\n                    PdfParser.PdfDict(\n                        {\n                            \"K\": -1,\n                            \"BlackIs1\": True,\n                            \"Columns\": width,\n                            \"Rows\": height,\n                        }\n                    )\n                ]\n            )\n        else:\n            filter = \"DCTDecode\"\n        dict_obj[\"ColorSpace\"] = PdfParser.PdfName(\"DeviceGray\")\n        procset = \"ImageB\"  # grayscale\n    elif im.mode == \"L\":\n        filter = \"DCTDecode\"\n        # params = f\"<< /Predictor 15 /Columns {width-2} >>\"\n        dict_obj[\"ColorSpace\"] = PdfParser.PdfName(\"DeviceGray\")\n        procset = \"ImageB\"  # grayscale\n    elif im.mode == \"LA\":\n        filter = \"JPXDecode\"\n        # params = f\"<< /Predictor 15 /Columns {width-2} >>\"\n        procset = \"ImageB\"  # grayscale\n        dict_obj[\"SMaskInData\"] = 1\n    elif im.mode == \"P\":\n        filter = \"ASCIIHexDecode\"\n        palette = im.getpalette()\n        dict_obj[\"ColorSpace\"] = [\n            PdfParser.PdfName(\"Indexed\"),\n            PdfParser.PdfName(\"DeviceRGB\"),\n            255,\n            PdfParser.PdfBinary(palette),\n        ]\n        procset = \"ImageI\"  # indexed color\n    elif im.mode == \"RGB\":\n        filter = \"DCTDecode\"\n        dict_obj[\"ColorSpace\"] = PdfParser.PdfName(\"DeviceRGB\")\n        procset = \"ImageC\"  # color images\n    elif im.mode == \"RGBA\":\n        filter = \"JPXDecode\"\n        procset = \"ImageC\"  # color images\n        dict_obj[\"SMaskInData\"] = 1\n    elif im.mode == \"CMYK\":\n        filter = \"DCTDecode\"\n        dict_obj[\"ColorSpace\"] = PdfParser.PdfName(\"DeviceCMYK\")\n        procset = \"ImageC\"  # color images\n        decode = [1, 0, 1, 0, 1, 0, 1, 0]\n    else:\n        msg = f\"cannot save mode {im.mode}\"\n        raise ValueError(msg)\n\n    #\n    # image\n\n    op = io.BytesIO()\n\n    if filter == \"ASCIIHexDecode\":\n        ImageFile._save(im, op, [(\"hex\", (0, 0) + im.size, 0, im.mode)])\n    elif filter == \"CCITTFaxDecode\":\n        im.save(\n            op,\n            \"TIFF\",\n            compression=\"group4\",\n            # use a single strip\n            strip_size=math.ceil(im.width / 8) * im.height,\n        )\n    elif filter == \"DCTDecode\":\n        Image.SAVE[\"JPEG\"](im, op, filename)\n    elif filter == \"JPXDecode\":\n        del dict_obj[\"BitsPerComponent\"]\n        Image.SAVE[\"JPEG2000\"](im, op, filename)\n    elif filter == \"FlateDecode\":\n        ImageFile._save(im, op, [(\"zip\", (0, 0) + im.size, 0, im.mode)])\n    elif filter == \"RunLengthDecode\":\n        ImageFile._save(im, op, [(\"packbits\", (0, 0) + im.size, 0, im.mode)])\n    else:\n        msg = f\"unsupported PDF filter ({filter})\"\n        raise ValueError(msg)\n\n    stream = op.getvalue()\n    if filter == \"CCITTFaxDecode\":\n        stream = stream[8:]\n        filter = PdfParser.PdfArray([PdfParser.PdfName(filter)])\n    else:\n        filter = PdfParser.PdfName(filter)\n\n    existing_pdf.write_obj(\n        image_refs[page_number],\n        stream=stream,\n        Type=PdfParser.PdfName(\"XObject\"),\n        Subtype=PdfParser.PdfName(\"Image\"),\n        Width=width,  # * 72.0 / x_resolution,\n        Height=height,  # * 72.0 / y_resolution,\n        Filter=filter,\n        Decode=decode,\n        DecodeParms=params,\n        **dict_obj,\n    )\n\n    return procset",
                            "ast_type_str": "FunctionDef",
                            "start_lineno": 49,
                            "end_lineno": 168,
                            "parent": null
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                },
                {
                    "descriptor": {
                        "old_range": {
                            "start": 165,
                            "length": 7
                        },
                        "new_range": {
                            "start": 173,
                            "length": 7
                        },
                        "section": "def _write_image(im, filename, existing_pdf, image_refs):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "        **dict_obj,",
                                "type": "context"
                            },
                            {
                                "content": "    )",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "    return procset",
                                "type": "deleted"
                            },
                            {
                                "content": "    return image_ref, procset",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "def _save(im, fp, filename, save_all=False):",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "src/PIL/PdfImagePlugin.py",
                            "type": "function",
                            "name": "_write_image",
                            "content": "def _write_image(im, filename, existing_pdf, image_refs):\n    # FIXME: Should replace ASCIIHexDecode with RunLengthDecode\n    # (packbits) or LZWDecode (tiff/lzw compression).  Note that\n    # PDF 1.2 also supports Flatedecode (zip compression).\n\n    params = None\n    decode = None\n\n    #\n    # Get image characteristics\n\n    width, height = im.size\n\n    dict_obj = {\"BitsPerComponent\": 8}\n    if im.mode == \"1\":\n        if features.check(\"libtiff\"):\n            filter = \"CCITTFaxDecode\"\n            dict_obj[\"BitsPerComponent\"] = 1\n            params = PdfParser.PdfArray(\n                [\n                    PdfParser.PdfDict(\n                        {\n                            \"K\": -1,\n                            \"BlackIs1\": True,\n                            \"Columns\": width,\n                            \"Rows\": height,\n                        }\n                    )\n                ]\n            )\n        else:\n            filter = \"DCTDecode\"\n        dict_obj[\"ColorSpace\"] = PdfParser.PdfName(\"DeviceGray\")\n        procset = \"ImageB\"  # grayscale\n    elif im.mode == \"L\":\n        filter = \"DCTDecode\"\n        # params = f\"<< /Predictor 15 /Columns {width-2} >>\"\n        dict_obj[\"ColorSpace\"] = PdfParser.PdfName(\"DeviceGray\")\n        procset = \"ImageB\"  # grayscale\n    elif im.mode == \"LA\":\n        filter = \"JPXDecode\"\n        # params = f\"<< /Predictor 15 /Columns {width-2} >>\"\n        procset = \"ImageB\"  # grayscale\n        dict_obj[\"SMaskInData\"] = 1\n    elif im.mode == \"P\":\n        filter = \"ASCIIHexDecode\"\n        palette = im.getpalette()\n        dict_obj[\"ColorSpace\"] = [\n            PdfParser.PdfName(\"Indexed\"),\n            PdfParser.PdfName(\"DeviceRGB\"),\n            255,\n            PdfParser.PdfBinary(palette),\n        ]\n        procset = \"ImageI\"  # indexed color\n    elif im.mode == \"RGB\":\n        filter = \"DCTDecode\"\n        dict_obj[\"ColorSpace\"] = PdfParser.PdfName(\"DeviceRGB\")\n        procset = \"ImageC\"  # color images\n    elif im.mode == \"RGBA\":\n        filter = \"JPXDecode\"\n        procset = \"ImageC\"  # color images\n        dict_obj[\"SMaskInData\"] = 1\n    elif im.mode == \"CMYK\":\n        filter = \"DCTDecode\"\n        dict_obj[\"ColorSpace\"] = PdfParser.PdfName(\"DeviceCMYK\")\n        procset = \"ImageC\"  # color images\n        decode = [1, 0, 1, 0, 1, 0, 1, 0]\n    else:\n        msg = f\"cannot save mode {im.mode}\"\n        raise ValueError(msg)\n\n    #\n    # image\n\n    op = io.BytesIO()\n\n    if filter == \"ASCIIHexDecode\":\n        ImageFile._save(im, op, [(\"hex\", (0, 0) + im.size, 0, im.mode)])\n    elif filter == \"CCITTFaxDecode\":\n        im.save(\n            op,\n            \"TIFF\",\n            compression=\"group4\",\n            # use a single strip\n            strip_size=math.ceil(im.width / 8) * im.height,\n        )\n    elif filter == \"DCTDecode\":\n        Image.SAVE[\"JPEG\"](im, op, filename)\n    elif filter == \"JPXDecode\":\n        del dict_obj[\"BitsPerComponent\"]\n        Image.SAVE[\"JPEG2000\"](im, op, filename)\n    elif filter == \"FlateDecode\":\n        ImageFile._save(im, op, [(\"zip\", (0, 0) + im.size, 0, im.mode)])\n    elif filter == \"RunLengthDecode\":\n        ImageFile._save(im, op, [(\"packbits\", (0, 0) + im.size, 0, im.mode)])\n    else:\n        msg = f\"unsupported PDF filter ({filter})\"\n        raise ValueError(msg)\n\n    stream = op.getvalue()\n    if filter == \"CCITTFaxDecode\":\n        stream = stream[8:]\n        filter = PdfParser.PdfArray([PdfParser.PdfName(filter)])\n    else:\n        filter = PdfParser.PdfName(filter)\n\n    existing_pdf.write_obj(\n        image_refs[page_number],\n        stream=stream,\n        Type=PdfParser.PdfName(\"XObject\"),\n        Subtype=PdfParser.PdfName(\"Image\"),\n        Width=width,  # * 72.0 / x_resolution,\n        Height=height,  # * 72.0 / y_resolution,\n        Filter=filter,\n        Decode=decode,\n        DecodeParms=params,\n        **dict_obj,\n    )\n\n    return procset",
                            "ast_type_str": "FunctionDef",
                            "start_lineno": 49,
                            "end_lineno": 168,
                            "parent": null
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                },
                {
                    "descriptor": {
                        "old_range": {
                            "start": 231,
                            "length": 6
                        },
                        "new_range": {
                            "start": 239,
                            "length": 9
                        },
                        "section": "def _save(im, fp, filename, save_all=False):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "        number_of_pages += im_number_of_pages",
                                "type": "context"
                            },
                            {
                                "content": "        for i in range(im_number_of_pages):",
                                "type": "context"
                            },
                            {
                                "content": "            image_refs.append(existing_pdf.next_object_id(0))",
                                "type": "context"
                            },
                            {
                                "content": "            if im.mode == \"P\" and \"transparency\" in im.info:",
                                "type": "added"
                            },
                            {
                                "content": "                image_refs.append(existing_pdf.next_object_id(0))",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "            page_refs.append(existing_pdf.next_object_id(0))",
                                "type": "context"
                            },
                            {
                                "content": "            contents_refs.append(existing_pdf.next_object_id(0))",
                                "type": "context"
                            },
                            {
                                "content": "            existing_pdf.pages.append(page_refs[-1])",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "src/PIL/PdfImagePlugin.py",
                            "type": "function",
                            "name": "_save",
                            "content": "def _save(im, fp, filename, save_all=False):\n    is_appending = im.encoderinfo.get(\"append\", False)\n    if is_appending:\n        existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode=\"r+b\")\n    else:\n        existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode=\"w+b\")\n\n    dpi = im.encoderinfo.get(\"dpi\")\n    if dpi:\n        x_resolution = dpi[0]\n        y_resolution = dpi[1]\n    else:\n        x_resolution = y_resolution = im.encoderinfo.get(\"resolution\", 72.0)\n\n    info = {\n        \"title\": None\n        if is_appending\n        else os.path.splitext(os.path.basename(filename))[0],\n        \"author\": None,\n        \"subject\": None,\n        \"keywords\": None,\n        \"creator\": None,\n        \"producer\": None,\n        \"creationDate\": None if is_appending else time.gmtime(),\n        \"modDate\": None if is_appending else time.gmtime(),\n    }\n    for k, default in info.items():\n        v = im.encoderinfo.get(k) if k in im.encoderinfo else default\n        if v:\n            existing_pdf.info[k[0].upper() + k[1:]] = v\n\n    #\n    # make sure image data is available\n    im.load()\n\n    existing_pdf.start_writing()\n    existing_pdf.write_header()\n    existing_pdf.write_comment(f\"created by Pillow {__version__} PDF driver\")\n\n    #\n    # pages\n    ims = [im]\n    if save_all:\n        append_images = im.encoderinfo.get(\"append_images\", [])\n        for append_im in append_images:\n            append_im.encoderinfo = im.encoderinfo.copy()\n            ims.append(append_im)\n    number_of_pages = 0\n    image_refs = []\n    page_refs = []\n    contents_refs = []\n    for im in ims:\n        im_number_of_pages = 1\n        if save_all:\n            try:\n                im_number_of_pages = im.n_frames\n            except AttributeError:\n                # Image format does not have n_frames.\n                # It is a single frame image\n                pass\n        number_of_pages += im_number_of_pages\n        for i in range(im_number_of_pages):\n            image_refs.append(existing_pdf.next_object_id(0))\n            if im.mode == \"P\" and \"transparency\" in im.info:\n                image_refs.append(existing_pdf.next_object_id(0))\n\n            page_refs.append(existing_pdf.next_object_id(0))\n            contents_refs.append(existing_pdf.next_object_id(0))\n            existing_pdf.pages.append(page_refs[-1])\n\n    #\n    # catalog and list of pages\n    existing_pdf.write_catalog()\n\n    page_number = 0\n    for im_sequence in ims:\n        im_pages = ImageSequence.Iterator(im_sequence) if save_all else [im_sequence]\n        for im in im_pages:\n            image_ref, procset = _write_image(im, filename, existing_pdf, image_refs)\n\n            #\n            # page\n\n            existing_pdf.write_page(\n                page_refs[page_number],\n                Resources=PdfParser.PdfDict(\n                    ProcSet=[PdfParser.PdfName(\"PDF\"), PdfParser.PdfName(procset)],\n                    XObject=PdfParser.PdfDict(image=image_ref),\n                ),\n                MediaBox=[\n                    0,\n                    0,\n                    im.width * 72.0 / x_resolution,\n                    im.height * 72.0 / y_resolution,\n                ],\n                Contents=contents_refs[page_number],\n            )\n\n            #\n            # page contents\n\n            page_contents = b\"q %f 0 0 %f 0 0 cm /image Do Q\\n\" % (\n                im.width * 72.0 / x_resolution,\n                im.height * 72.0 / y_resolution,\n            )\n\n            existing_pdf.write_obj(contents_refs[page_number], stream=page_contents)\n\n            page_number += 1\n\n    #\n    # trailer\n    existing_pdf.write_xref_and_trailer()\n    if hasattr(fp, \"flush\"):\n        fp.flush()\n    existing_pdf.close()",
                            "ast_type_str": "FunctionDef",
                            "start_lineno": 179,
                            "end_lineno": 294,
                            "parent": null
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                },
                {
                    "descriptor": {
                        "old_range": {
                            "start": 243,
                            "length": 7
                        },
                        "new_range": {
                            "start": 254,
                            "length": 7
                        },
                        "section": "def _save(im, fp, filename, save_all=False):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "    for im_sequence in ims:",
                                "type": "context"
                            },
                            {
                                "content": "        im_pages = ImageSequence.Iterator(im_sequence) if save_all else [im_sequence]",
                                "type": "context"
                            },
                            {
                                "content": "        for im in im_pages:",
                                "type": "context"
                            },
                            {
                                "content": "            procset = _write_image(im, filename, existing_pdfs, image_refs)",
                                "type": "deleted"
                            },
                            {
                                "content": "            image_ref, procset = _write_image(im, filename, existing_pdf, image_refs)",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "            #",
                                "type": "context"
                            },
                            {
                                "content": "            # page",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "src/PIL/PdfImagePlugin.py",
                            "type": "function",
                            "name": "_save",
                            "content": "def _save(im, fp, filename, save_all=False):\n    is_appending = im.encoderinfo.get(\"append\", False)\n    if is_appending:\n        existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode=\"r+b\")\n    else:\n        existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode=\"w+b\")\n\n    dpi = im.encoderinfo.get(\"dpi\")\n    if dpi:\n        x_resolution = dpi[0]\n        y_resolution = dpi[1]\n    else:\n        x_resolution = y_resolution = im.encoderinfo.get(\"resolution\", 72.0)\n\n    info = {\n        \"title\": None\n        if is_appending\n        else os.path.splitext(os.path.basename(filename))[0],\n        \"author\": None,\n        \"subject\": None,\n        \"keywords\": None,\n        \"creator\": None,\n        \"producer\": None,\n        \"creationDate\": None if is_appending else time.gmtime(),\n        \"modDate\": None if is_appending else time.gmtime(),\n    }\n    for k, default in info.items():\n        v = im.encoderinfo.get(k) if k in im.encoderinfo else default\n        if v:\n            existing_pdf.info[k[0].upper() + k[1:]] = v\n\n    #\n    # make sure image data is available\n    im.load()\n\n    existing_pdf.start_writing()\n    existing_pdf.write_header()\n    existing_pdf.write_comment(f\"created by Pillow {__version__} PDF driver\")\n\n    #\n    # pages\n    ims = [im]\n    if save_all:\n        append_images = im.encoderinfo.get(\"append_images\", [])\n        for append_im in append_images:\n            append_im.encoderinfo = im.encoderinfo.copy()\n            ims.append(append_im)\n    number_of_pages = 0\n    image_refs = []\n    page_refs = []\n    contents_refs = []\n    for im in ims:\n        im_number_of_pages = 1\n        if save_all:\n            try:\n                im_number_of_pages = im.n_frames\n            except AttributeError:\n                # Image format does not have n_frames.\n                # It is a single frame image\n                pass\n        number_of_pages += im_number_of_pages\n        for i in range(im_number_of_pages):\n            image_refs.append(existing_pdf.next_object_id(0))\n            page_refs.append(existing_pdf.next_object_id(0))\n            contents_refs.append(existing_pdf.next_object_id(0))\n            existing_pdf.pages.append(page_refs[-1])\n\n    #\n    # catalog and list of pages\n    existing_pdf.write_catalog()\n\n    page_number = 0\n    for im_sequence in ims:\n        im_pages = ImageSequence.Iterator(im_sequence) if save_all else [im_sequence]\n        for im in im_pages:\n            procset = _write_image(im, filename, existing_pdfs, image_refs)\n\n            #\n            # page\n\n            existing_pdf.write_page(\n                page_refs[page_number],\n                Resources=PdfParser.PdfDict(\n                    ProcSet=[PdfParser.PdfName(\"PDF\"), PdfParser.PdfName(procset)],\n                    XObject=PdfParser.PdfDict(image=image_refs[page_number]),\n                ),\n                MediaBox=[\n                    0,\n                    0,\n                    im.width * 72.0 / x_resolution,\n                    im.height * 72.0 / y_resolution,\n                ],\n                Contents=contents_refs[page_number],\n            )\n\n            #\n            # page contents\n\n            page_contents = b\"q %f 0 0 %f 0 0 cm /image Do Q\\n\" % (\n                im.width * 72.0 / x_resolution,\n                im.height * 72.0 / y_resolution,\n            )\n\n            existing_pdf.write_obj(contents_refs[page_number], stream=page_contents)\n\n            page_number += 1\n\n    #\n    # trailer\n    existing_pdf.write_xref_and_trailer()\n    if hasattr(fp, \"flush\"):\n        fp.flush()\n    existing_pdf.close()",
                            "ast_type_str": "FunctionDef",
                            "start_lineno": 171,
                            "end_lineno": 283,
                            "parent": null
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                },
                {
                    "descriptor": {
                        "old_range": {
                            "start": 252,
                            "length": 7
                        },
                        "new_range": {
                            "start": 263,
                            "length": 7
                        },
                        "section": "def _save(im, fp, filename, save_all=False):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "                page_refs[page_number],",
                                "type": "context"
                            },
                            {
                                "content": "                Resources=PdfParser.PdfDict(",
                                "type": "context"
                            },
                            {
                                "content": "                    ProcSet=[PdfParser.PdfName(\"PDF\"), PdfParser.PdfName(procset)],",
                                "type": "context"
                            },
                            {
                                "content": "                    XObject=PdfParser.PdfDict(image=image_refs[page_number]),",
                                "type": "deleted"
                            },
                            {
                                "content": "                    XObject=PdfParser.PdfDict(image=image_ref),",
                                "type": "added"
                            },
                            {
                                "content": "                ),",
                                "type": "context"
                            },
                            {
                                "content": "                MediaBox=[",
                                "type": "context"
                            },
                            {
                                "content": "                    0,",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "src/PIL/PdfImagePlugin.py",
                            "type": "function",
                            "name": "_save",
                            "content": "def _save(im, fp, filename, save_all=False):\n    is_appending = im.encoderinfo.get(\"append\", False)\n    if is_appending:\n        existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode=\"r+b\")\n    else:\n        existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode=\"w+b\")\n\n    dpi = im.encoderinfo.get(\"dpi\")\n    if dpi:\n        x_resolution = dpi[0]\n        y_resolution = dpi[1]\n    else:\n        x_resolution = y_resolution = im.encoderinfo.get(\"resolution\", 72.0)\n\n    info = {\n        \"title\": None\n        if is_appending\n        else os.path.splitext(os.path.basename(filename))[0],\n        \"author\": None,\n        \"subject\": None,\n        \"keywords\": None,\n        \"creator\": None,\n        \"producer\": None,\n        \"creationDate\": None if is_appending else time.gmtime(),\n        \"modDate\": None if is_appending else time.gmtime(),\n    }\n    for k, default in info.items():\n        v = im.encoderinfo.get(k) if k in im.encoderinfo else default\n        if v:\n            existing_pdf.info[k[0].upper() + k[1:]] = v\n\n    #\n    # make sure image data is available\n    im.load()\n\n    existing_pdf.start_writing()\n    existing_pdf.write_header()\n    existing_pdf.write_comment(f\"created by Pillow {__version__} PDF driver\")\n\n    #\n    # pages\n    ims = [im]\n    if save_all:\n        append_images = im.encoderinfo.get(\"append_images\", [])\n        for append_im in append_images:\n            append_im.encoderinfo = im.encoderinfo.copy()\n            ims.append(append_im)\n    number_of_pages = 0\n    image_refs = []\n    page_refs = []\n    contents_refs = []\n    for im in ims:\n        im_number_of_pages = 1\n        if save_all:\n            try:\n                im_number_of_pages = im.n_frames\n            except AttributeError:\n                # Image format does not have n_frames.\n                # It is a single frame image\n                pass\n        number_of_pages += im_number_of_pages\n        for i in range(im_number_of_pages):\n            image_refs.append(existing_pdf.next_object_id(0))\n            page_refs.append(existing_pdf.next_object_id(0))\n            contents_refs.append(existing_pdf.next_object_id(0))\n            existing_pdf.pages.append(page_refs[-1])\n\n    #\n    # catalog and list of pages\n    existing_pdf.write_catalog()\n\n    page_number = 0\n    for im_sequence in ims:\n        im_pages = ImageSequence.Iterator(im_sequence) if save_all else [im_sequence]\n        for im in im_pages:\n            procset = _write_image(im, filename, existing_pdfs, image_refs)\n\n            #\n            # page\n\n            existing_pdf.write_page(\n                page_refs[page_number],\n                Resources=PdfParser.PdfDict(\n                    ProcSet=[PdfParser.PdfName(\"PDF\"), PdfParser.PdfName(procset)],\n                    XObject=PdfParser.PdfDict(image=image_refs[page_number]),\n                ),\n                MediaBox=[\n                    0,\n                    0,\n                    im.width * 72.0 / x_resolution,\n                    im.height * 72.0 / y_resolution,\n                ],\n                Contents=contents_refs[page_number],\n            )\n\n            #\n            # page contents\n\n            page_contents = b\"q %f 0 0 %f 0 0 cm /image Do Q\\n\" % (\n                im.width * 72.0 / x_resolution,\n                im.height * 72.0 / y_resolution,\n            )\n\n            existing_pdf.write_obj(contents_refs[page_number], stream=page_contents)\n\n            page_number += 1\n\n    #\n    # trailer\n    existing_pdf.write_xref_and_trailer()\n    if hasattr(fp, \"flush\"):\n        fp.flush()\n    existing_pdf.close()",
                            "ast_type_str": "FunctionDef",
                            "start_lineno": 171,
                            "end_lineno": 283,
                            "parent": null
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                }
            ]
        }
    ],
    "old_commit_hash": "a70ea82eb5c2cd073e1fe7cab0dca32b93fdcb9f^",
    "new_commit_hash": "a70ea82eb5c2cd073e1fe7cab0dca32b93fdcb9f",
    "commit_message": "Write P transparency as SMask",
    "commit_date": "2023-08-07T13:53:19+10:00",
    "metadata": {}
}
{
    "repo_name": "pillow",
    "new_commit_hash": "a70ea82eb5c2cd073e1fe7cab0dca32b93fdcb9f",
    "test_file_codes": [
        "import io\nimport os\nimport os.path\nimport tempfile\nimport time\n\nimport pytest\n\nfrom PIL import Image, PdfParser, features\n\nfrom .helper import hopper, mark_if_feature_version, skip_unless_feature\n\n\ndef helper_save_as_pdf(tmp_path, mode, **kwargs):\n    # Arrange\n    im = hopper(mode)\n    outfile = str(tmp_path / (\"temp_\" + mode + \".pdf\"))\n\n    # Act\n    im.save(outfile, **kwargs)\n\n    # Assert\n    assert os.path.isfile(outfile)\n    assert os.path.getsize(outfile) > 0\n    with PdfParser.PdfParser(outfile) as pdf:\n        if kwargs.get(\"append_images\", False) or kwargs.get(\"append\", False):\n            assert len(pdf.pages) > 1\n        else:\n            assert len(pdf.pages) > 0\n    with open(outfile, \"rb\") as fp:\n        contents = fp.read()\n    size = tuple(\n        float(d) for d in contents.split(b\"/MediaBox [ 0 0 \")[1].split(b\"]\")[0].split()\n    )\n    assert im.size == size\n\n    return outfile\n\n\n@pytest.mark.parametrize(\"mode\", (\"L\", \"P\", \"RGB\", \"CMYK\"))\ndef test_save(tmp_path, mode):\n    helper_save_as_pdf(tmp_path, mode)\n\n\n@skip_unless_feature(\"jpg_2000\")\n@pytest.mark.parametrize(\"mode\", (\"LA\", \"RGBA\"))\ndef test_save_alpha(tmp_path, mode):\n    helper_save_as_pdf(tmp_path, mode)\n\n\ndef test_p_alpha(tmp_path):\n    # Arrange\n    outfile = str(tmp_path / \"temp.pdf\")\n    with Image.open(\"Tests/images/pil123p.png\") as im:\n        assert im.mode == \"P\"\n        assert isinstance(im.info[\"transparency\"], bytes)\n\n        # Act\n        im.save(outfile)\n\n    # Assert\n    with open(outfile, \"rb\") as fp:\n        contents = fp.read()\n    assert b\"SMask\" in contents\n\n\ndef test_monochrome(tmp_path):\n    # Arrange\n    mode = \"1\"\n\n    # Act / Assert\n    outfile = helper_save_as_pdf(tmp_path, mode)\n    assert os.path.getsize(outfile) < (5000 if features.check(\"libtiff\") else 15000)\n\n\ndef test_unsupported_mode(tmp_path):\n    im = hopper(\"PA\")\n    outfile = str(tmp_path / \"temp_PA.pdf\")\n\n    with pytest.raises(ValueError):\n        im.save(outfile)\n\n\ndef test_resolution(tmp_path):\n    im = hopper()\n\n    outfile = str(tmp_path / \"temp.pdf\")\n    im.save(outfile, resolution=150)\n\n    with open(outfile, \"rb\") as fp:\n        contents = fp.read()\n\n    size = tuple(\n        float(d)\n        for d in contents.split(b\"stream\\nq \")[1].split(b\" 0 0 cm\")[0].split(b\" 0 0 \")\n    )\n    assert size == (61.44, 61.44)\n\n    size = tuple(\n        float(d) for d in contents.split(b\"/MediaBox [ 0 0 \")[1].split(b\"]\")[0].split()\n    )\n    assert size == (61.44, 61.44)\n\n\n@pytest.mark.parametrize(\n    \"params\",\n    (\n        {\"dpi\": (75, 150)},\n        {\"dpi\": (75, 150), \"resolution\": 200},\n    ),\n)\ndef test_dpi(params, tmp_path):\n    im = hopper()\n\n    outfile = str(tmp_path / \"temp.pdf\")\n    im.save(outfile, **params)\n\n    with open(outfile, \"rb\") as fp:\n        contents = fp.read()\n\n    size = tuple(\n        float(d)\n        for d in contents.split(b\"stream\\nq \")[1].split(b\" 0 0 cm\")[0].split(b\" 0 0 \")\n    )\n    assert size == (122.88, 61.44)\n\n    size = tuple(\n        float(d) for d in contents.split(b\"/MediaBox [ 0 0 \")[1].split(b\"]\")[0].split()\n    )\n    assert size == (122.88, 61.44)\n\n\n@mark_if_feature_version(\n    pytest.mark.valgrind_known_error, \"libjpeg_turbo\", \"2.0\", reason=\"Known Failing\"\n)\ndef test_save_all(tmp_path):\n    # Single frame image\n    helper_save_as_pdf(tmp_path, \"RGB\", save_all=True)\n\n    # Multiframe image\n    with Image.open(\"Tests/images/dispose_bgnd.gif\") as im:\n        outfile = str(tmp_path / \"temp.pdf\")\n        im.save(outfile, save_all=True)\n\n        assert os.path.isfile(outfile)\n        assert os.path.getsize(outfile) > 0\n\n        # Append images\n        ims = [hopper()]\n        im.copy().save(outfile, save_all=True, append_images=ims)\n\n        assert os.path.isfile(outfile)\n        assert os.path.getsize(outfile) > 0\n\n        # Test appending using a generator\n        def im_generator(ims):\n            yield from ims\n\n        im.save(outfile, save_all=True, append_images=im_generator(ims))\n\n    assert os.path.isfile(outfile)\n    assert os.path.getsize(outfile) > 0\n\n    # Append JPEG images\n    with Image.open(\"Tests/images/flower.jpg\") as jpeg:\n        jpeg.save(outfile, save_all=True, append_images=[jpeg.copy()])\n\n    assert os.path.isfile(outfile)\n    assert os.path.getsize(outfile) > 0\n\n\ndef test_multiframe_normal_save(tmp_path):\n    # Test saving a multiframe image without save_all\n    with Image.open(\"Tests/images/dispose_bgnd.gif\") as im:\n        outfile = str(tmp_path / \"temp.pdf\")\n        im.save(outfile)\n\n    assert os.path.isfile(outfile)\n    assert os.path.getsize(outfile) > 0\n\n\ndef test_pdf_open(tmp_path):\n    # fail on a buffer full of null bytes\n    with pytest.raises(PdfParser.PdfFormatError):\n        PdfParser.PdfParser(buf=bytearray(65536))\n\n    # make an empty PDF object\n    with PdfParser.PdfParser() as empty_pdf:\n        assert len(empty_pdf.pages) == 0\n        assert len(empty_pdf.info) == 0\n        assert not empty_pdf.should_close_buf\n        assert not empty_pdf.should_close_file\n\n    # make a PDF file\n    pdf_filename = helper_save_as_pdf(tmp_path, \"RGB\")\n\n    # open the PDF file\n    with PdfParser.PdfParser(filename=pdf_filename) as hopper_pdf:\n        assert len(hopper_pdf.pages) == 1\n        assert hopper_pdf.should_close_buf\n        assert hopper_pdf.should_close_file\n\n    # read a PDF file from a buffer with a non-zero offset\n    with open(pdf_filename, \"rb\") as f:\n        content = b\"xyzzy\" + f.read()\n    with PdfParser.PdfParser(buf=content, start_offset=5) as hopper_pdf:\n        assert len(hopper_pdf.pages) == 1\n        assert not hopper_pdf.should_close_buf\n        assert not hopper_pdf.should_close_file\n\n    # read a PDF file from an already open file\n    with open(pdf_filename, \"rb\") as f:\n        with PdfParser.PdfParser(f=f) as hopper_pdf:\n            assert len(hopper_pdf.pages) == 1\n            assert hopper_pdf.should_close_buf\n            assert not hopper_pdf.should_close_file\n\n\ndef test_pdf_append_fails_on_nonexistent_file():\n    im = hopper(\"RGB\")\n    with tempfile.TemporaryDirectory() as temp_dir:\n        with pytest.raises(OSError):\n            im.save(os.path.join(temp_dir, \"nonexistent.pdf\"), append=True)\n\n\ndef check_pdf_pages_consistency(pdf):\n    pages_info = pdf.read_indirect(pdf.pages_ref)\n    assert b\"Parent\" not in pages_info\n    assert b\"Kids\" in pages_info\n    kids_not_used = pages_info[b\"Kids\"]\n    for page_ref in pdf.pages:\n        while True:\n            if page_ref in kids_not_used:\n                kids_not_used.remove(page_ref)\n            page_info = pdf.read_indirect(page_ref)\n            assert b\"Parent\" in page_info\n            page_ref = page_info[b\"Parent\"]\n            if page_ref == pdf.pages_ref:\n                break\n        assert pdf.pages_ref == page_info[b\"Parent\"]\n    assert kids_not_used == []\n\n\ndef test_pdf_append(tmp_path):\n    # make a PDF file\n    pdf_filename = helper_save_as_pdf(tmp_path, \"RGB\", producer=\"PdfParser\")\n\n    # open it, check pages and info\n    with PdfParser.PdfParser(pdf_filename, mode=\"r+b\") as pdf:\n        assert len(pdf.pages) == 1\n        assert len(pdf.info) == 4\n        assert pdf.info.Title == os.path.splitext(os.path.basename(pdf_filename))[0]\n        assert pdf.info.Producer == \"PdfParser\"\n        assert b\"CreationDate\" in pdf.info\n        assert b\"ModDate\" in pdf.info\n        check_pdf_pages_consistency(pdf)\n\n        # append some info\n        pdf.info.Title = \"abc\"\n        pdf.info.Author = \"def\"\n        pdf.info.Subject = \"ghi\\uABCD\"\n        pdf.info.Keywords = \"qw)e\\\\r(ty\"\n        pdf.info.Creator = \"hopper()\"\n        pdf.start_writing()\n        pdf.write_xref_and_trailer()\n\n    # open it again, check pages and info again\n    with PdfParser.PdfParser(pdf_filename) as pdf:\n        assert len(pdf.pages) == 1\n        assert len(pdf.info) == 8\n        assert pdf.info.Title == \"abc\"\n        assert b\"CreationDate\" in pdf.info\n        assert b\"ModDate\" in pdf.info\n        check_pdf_pages_consistency(pdf)\n\n    # append two images\n    mode_cmyk = hopper(\"CMYK\")\n    mode_p = hopper(\"P\")\n    mode_cmyk.save(pdf_filename, append=True, save_all=True, append_images=[mode_p])\n\n    # open the PDF again, check pages and info again\n    with PdfParser.PdfParser(pdf_filename) as pdf:\n        assert len(pdf.pages) == 3\n        assert len(pdf.info) == 8\n        assert PdfParser.decode_text(pdf.info[b\"Title\"]) == \"abc\"\n        assert pdf.info.Title == \"abc\"\n        assert pdf.info.Producer == \"PdfParser\"\n        assert pdf.info.Keywords == \"qw)e\\\\r(ty\"\n        assert pdf.info.Subject == \"ghi\\uABCD\"\n        assert b\"CreationDate\" in pdf.info\n        assert b\"ModDate\" in pdf.info\n        check_pdf_pages_consistency(pdf)\n\n\ndef test_pdf_info(tmp_path):\n    # make a PDF file\n    pdf_filename = helper_save_as_pdf(\n        tmp_path,\n        \"RGB\",\n        title=\"title\",\n        author=\"author\",\n        subject=\"subject\",\n        keywords=\"keywords\",\n        creator=\"creator\",\n        producer=\"producer\",\n        creationDate=time.strptime(\"2000\", \"%Y\"),\n        modDate=time.strptime(\"2001\", \"%Y\"),\n    )\n\n    # open it, check pages and info\n    with PdfParser.PdfParser(pdf_filename) as pdf:\n        assert len(pdf.info) == 8\n        assert pdf.info.Title == \"title\"\n        assert pdf.info.Author == \"author\"\n        assert pdf.info.Subject == \"subject\"\n        assert pdf.info.Keywords == \"keywords\"\n        assert pdf.info.Creator == \"creator\"\n        assert pdf.info.Producer == \"producer\"\n        assert pdf.info.CreationDate == time.strptime(\"2000\", \"%Y\")\n        assert pdf.info.ModDate == time.strptime(\"2001\", \"%Y\")\n        check_pdf_pages_consistency(pdf)\n\n\ndef test_pdf_append_to_bytesio():\n    im = hopper(\"RGB\")\n    f = io.BytesIO()\n    im.save(f, format=\"PDF\")\n    initial_size = len(f.getvalue())\n    assert initial_size > 0\n    im = hopper(\"P\")\n    f = io.BytesIO(f.getvalue())\n    im.save(f, format=\"PDF\", append=True)\n    assert len(f.getvalue()) > initial_size\n\n\n@pytest.mark.timeout(1)\n@pytest.mark.skipif(\"PILLOW_VALGRIND_TEST\" in os.environ, reason=\"Valgrind is slower\")\n@pytest.mark.parametrize(\"newline\", (b\"\\r\", b\"\\n\"))\ndef test_redos(newline):\n    malicious = b\" trailer<<>>\" + newline * 3456\n\n    # This particular exception isn't relevant here.\n    # The important thing is it doesn't timeout, cause a ReDoS (CVE-2021-25292).\n    with pytest.raises(PdfParser.PdfFormatError):\n        PdfParser.PdfParser(buf=malicious)\n"
    ],
    "test_file_names": [
        "test_1.py"
    ],
    "setup_res_code": 0,
    "setup_res_stdout": "Starting Pillow installation attempts...\nVerifying Pillow installation...\n✅ Pillow installation successful!\nSuccessfully installed Pillow\n",
    "setup_res_stderr": "Using CPython 3.9.21\nCreating virtual environment at: .venv\nActivate with: source .venv/bin/activate\nResolved 12 packages in 17ms\nInstalled 12 packages in 160ms\n + coverage==7.6.10\n + exceptiongroup==1.2.2\n + iniconfig==2.0.0\n + packaging==24.2\n + pluggy==1.5.0\n + pyqt5==5.15.11\n + pyqt5-qt5==5.15.16\n + pyqt5-sip==12.16.1\n + pytest==8.3.4\n + pytest-cov==6.0.0\n + setuptools==75.8.0\n + tomli==2.2.1\nResolved 1 package in 764ms\nPrepared 1 package in 34.52s\nInstalled 1 package in 0.87ms\n + pillow==10.1.0.dev0 (from file:///home/gcpuser/buckets/local_repoeval_bucket/repos/pillow_a70ea82eb5c2cd073e1fe7cab0dca32b93fdcb9f)\n",
    "new_commit_res_code": 0,
    "new_commit_res_stdout": "\u001b[1m============================= test session starts ==============================\u001b[0m\nplatform linux -- Python 3.9.21, pytest-8.3.4, pluggy-1.5.0\nrootdir: /home/gcpuser/buckets/local_repoeval_bucket/repos/pillow_a70ea82eb5c2cd073e1fe7cab0dca32b93fdcb9f\nconfigfile: setup.cfg\nplugins: cov-6.0.0\ncollected 21 items\n\nr2e_tests/test_1.py \u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[33ms\u001b[0m\u001b[33ms\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m                                [100%]\u001b[0m\n\n==================================== PASSES ====================================\n\u001b[36m\u001b[1m=========================== short test summary info ============================\u001b[0m\n\u001b[32mPASSED\u001b[0m r2e_tests/test_1.py::\u001b[1mtest_save[L]\u001b[0m\n\u001b[32mPASSED\u001b[0m r2e_tests/test_1.py::\u001b[1mtest_save[P]\u001b[0m\n\u001b[32mPASSED\u001b[0m r2e_tests/test_1.py::\u001b[1mtest_save[RGB]\u001b[0m\n\u001b[32mPASSED\u001b[0m r2e_tests/test_1.py::\u001b[1mtest_save[CMYK]\u001b[0m\n\u001b[32mPASSED\u001b[0m r2e_tests/test_1.py::\u001b[1mtest_p_alpha\u001b[0m\n\u001b[32mPASSED\u001b[0m r2e_tests/test_1.py::\u001b[1mtest_monochrome\u001b[0m\n\u001b[32mPASSED\u001b[0m r2e_tests/test_1.py::\u001b[1mtest_unsupported_mode\u001b[0m\n\u001b[32mPASSED\u001b[0m r2e_tests/test_1.py::\u001b[1mtest_resolution\u001b[0m\n\u001b[32mPASSED\u001b[0m r2e_tests/test_1.py::\u001b[1mtest_dpi[params0]\u001b[0m\n\u001b[32mPASSED\u001b[0m r2e_tests/test_1.py::\u001b[1mtest_dpi[params1]\u001b[0m\n\u001b[32mPASSED\u001b[0m r2e_tests/test_1.py::\u001b[1mtest_save_all\u001b[0m\n\u001b[32mPASSED\u001b[0m r2e_tests/test_1.py::\u001b[1mtest_multiframe_normal_save\u001b[0m\n\u001b[32mPASSED\u001b[0m r2e_tests/test_1.py::\u001b[1mtest_pdf_open\u001b[0m\n\u001b[32mPASSED\u001b[0m r2e_tests/test_1.py::\u001b[1mtest_pdf_append_fails_on_nonexistent_file\u001b[0m\n\u001b[32mPASSED\u001b[0m r2e_tests/test_1.py::\u001b[1mtest_pdf_append\u001b[0m\n\u001b[32mPASSED\u001b[0m r2e_tests/test_1.py::\u001b[1mtest_pdf_info\u001b[0m\n\u001b[32mPASSED\u001b[0m r2e_tests/test_1.py::\u001b[1mtest_pdf_append_to_bytesio\u001b[0m\n\u001b[32mPASSED\u001b[0m r2e_tests/test_1.py::\u001b[1mtest_redos[\\r]\u001b[0m\n\u001b[32mPASSED\u001b[0m r2e_tests/test_1.py::\u001b[1mtest_redos[\\n]\u001b[0m\n\u001b[33mSKIPPED\u001b[0m [2] r2e_tests/test_1.py:45: jpg_2000 not available\n\u001b[32m======================== \u001b[32m\u001b[1m19 passed\u001b[0m, \u001b[33m2 skipped\u001b[0m\u001b[32m in 0.71s\u001b[0m\u001b[32m =========================\u001b[0m\n",
    "new_commit_res_stderr": "",
    "old_commit_res_code": 1,
    "old_commit_res_stdout": "\u001b[1m============================= test session starts ==============================\u001b[0m\nplatform linux -- Python 3.9.21, pytest-8.3.4, pluggy-1.5.0\nrootdir: /home/gcpuser/buckets/local_repoeval_bucket/repos/pillow_a70ea82eb5c2cd073e1fe7cab0dca32b93fdcb9f\nconfigfile: setup.cfg\nplugins: cov-6.0.0\ncollected 21 items\n\nr2e_tests/test_1.py \u001b[31mF\u001b[0m\u001b[31mF\u001b[0m\u001b[31mF\u001b[0m\u001b[31mF\u001b[0m\u001b[33ms\u001b[0m\u001b[33ms\u001b[0m\u001b[31mF\u001b[0m\u001b[31mF\u001b[0m\u001b[31mF\u001b[0m\u001b[31mF\u001b[0m\u001b[31mF\u001b[0m\u001b[31mF\u001b[0m\u001b[31mF\u001b[0m\u001b[31mF\u001b[0m\u001b[31mF\u001b[0m\u001b[32m.\u001b[0m\u001b[31mF\u001b[0m\u001b[31mF\u001b[0m\u001b[31mF\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[31m                                [100%]\u001b[0m\n\n=================================== FAILURES ===================================\n\u001b[31m\u001b[1m_________________________________ test_save[L] _________________________________\u001b[0m\n\ntmp_path = PosixPath('/tmp/pytest-of-gcpuser/pytest-509/test_save_L_0')\nmode = 'L'\n\n    @pytest.mark.parametrize(\"mode\", (\"L\", \"P\", \"RGB\", \"CMYK\"))\n    def test_save(tmp_path, mode):\n>       helper_save_as_pdf(tmp_path, mode)\n\n\u001b[1m\u001b[31mr2e_tests/test_1.py\u001b[0m:42: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\u001b[1m\u001b[31mr2e_tests/test_1.py\u001b[0m:20: in helper_save_as_pdf\n    im.save(outfile, **kwargs)\n\u001b[1m\u001b[31msrc/PIL/Image.py\u001b[0m:2416: in save\n    save_handler(self, fp, filename)\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\nim = <PIL.Image.Image image mode=L size=128x128 at 0x72FB80B58BE0>\nfp = <_io.BufferedRandom name='/tmp/pytest-of-gcpuser/pytest-509/test_save_L_0/temp_L.pdf'>\nfilename = '/tmp/pytest-of-gcpuser/pytest-509/test_save_L_0/temp_L.pdf'\nsave_all = False\n\n    def _save(im, fp, filename, save_all=False):\n        is_appending = im.encoderinfo.get(\"append\", False)\n        if is_appending:\n            existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode=\"r+b\")\n        else:\n            existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode=\"w+b\")\n    \n        dpi = im.encoderinfo.get(\"dpi\")\n        if dpi:\n            x_resolution = dpi[0]\n            y_resolution = dpi[1]\n        else:\n            x_resolution = y_resolution = im.encoderinfo.get(\"resolution\", 72.0)\n    \n        info = {\n            \"title\": None\n            if is_appending\n            else os.path.splitext(os.path.basename(filename))[0],\n            \"author\": None,\n            \"subject\": None,\n            \"keywords\": None,\n            \"creator\": None,\n            \"producer\": None,\n            \"creationDate\": None if is_appending else time.gmtime(),\n            \"modDate\": None if is_appending else time.gmtime(),\n        }\n        for k, default in info.items():\n            v = im.encoderinfo.get(k) if k in im.encoderinfo else default\n            if v:\n                existing_pdf.info[k[0].upper() + k[1:]] = v\n    \n        #\n        # make sure image data is available\n        im.load()\n    \n        existing_pdf.start_writing()\n        existing_pdf.write_header()\n        existing_pdf.write_comment(f\"created by Pillow {__version__} PDF driver\")\n    \n        #\n        # pages\n        ims = [im]\n        if save_all:\n            append_images = im.encoderinfo.get(\"append_images\", [])\n            for append_im in append_images:\n                append_im.encoderinfo = im.encoderinfo.copy()\n                ims.append(append_im)\n        number_of_pages = 0\n        image_refs = []\n        page_refs = []\n        contents_refs = []\n        for im in ims:\n            im_number_of_pages = 1\n            if save_all:\n                try:\n                    im_number_of_pages = im.n_frames\n                except AttributeError:\n                    # Image format does not have n_frames.\n                    # It is a single frame image\n                    pass\n            number_of_pages += im_number_of_pages\n            for i in range(im_number_of_pages):\n                image_refs.append(existing_pdf.next_object_id(0))\n                page_refs.append(existing_pdf.next_object_id(0))\n                contents_refs.append(existing_pdf.next_object_id(0))\n                existing_pdf.pages.append(page_refs[-1])\n    \n        #\n        # catalog and list of pages\n        existing_pdf.write_catalog()\n    \n        page_number = 0\n        for im_sequence in ims:\n            im_pages = ImageSequence.Iterator(im_sequence) if save_all else [im_sequence]\n            for im in im_pages:\n>               procset = _write_image(im, filename, existing_pdfs, image_refs)\n\u001b[1m\u001b[31mE               NameError: name 'existing_pdfs' is not defined\u001b[0m\n\n\u001b[1m\u001b[31msrc/PIL/PdfImagePlugin.py\u001b[0m:246: NameError\n\u001b[31m\u001b[1m_________________________________ test_save[P] _________________________________\u001b[0m\n\ntmp_path = PosixPath('/tmp/pytest-of-gcpuser/pytest-509/test_save_P_0')\nmode = 'P'\n\n    @pytest.mark.parametrize(\"mode\", (\"L\", \"P\", \"RGB\", \"CMYK\"))\n    def test_save(tmp_path, mode):\n>       helper_save_as_pdf(tmp_path, mode)\n\n\u001b[1m\u001b[31mr2e_tests/test_1.py\u001b[0m:42: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\u001b[1m\u001b[31mr2e_tests/test_1.py\u001b[0m:20: in helper_save_as_pdf\n    im.save(outfile, **kwargs)\n\u001b[1m\u001b[31msrc/PIL/Image.py\u001b[0m:2416: in save\n    save_handler(self, fp, filename)\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\nim = <PIL.Image.Image image mode=P size=128x128 at 0x72FB80665820>\nfp = <_io.BufferedRandom name='/tmp/pytest-of-gcpuser/pytest-509/test_save_P_0/temp_P.pdf'>\nfilename = '/tmp/pytest-of-gcpuser/pytest-509/test_save_P_0/temp_P.pdf'\nsave_all = False\n\n    def _save(im, fp, filename, save_all=False):\n        is_appending = im.encoderinfo.get(\"append\", False)\n        if is_appending:\n            existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode=\"r+b\")\n        else:\n            existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode=\"w+b\")\n    \n        dpi = im.encoderinfo.get(\"dpi\")\n        if dpi:\n            x_resolution = dpi[0]\n            y_resolution = dpi[1]\n        else:\n            x_resolution = y_resolution = im.encoderinfo.get(\"resolution\", 72.0)\n    \n        info = {\n            \"title\": None\n            if is_appending\n            else os.path.splitext(os.path.basename(filename))[0],\n            \"author\": None,\n            \"subject\": None,\n            \"keywords\": None,\n            \"creator\": None,\n            \"producer\": None,\n            \"creationDate\": None if is_appending else time.gmtime(),\n            \"modDate\": None if is_appending else time.gmtime(),\n        }\n        for k, default in info.items():\n            v = im.encoderinfo.get(k) if k in im.encoderinfo else default\n            if v:\n                existing_pdf.info[k[0].upper() + k[1:]] = v\n    \n        #\n        # make sure image data is available\n        im.load()\n    \n        existing_pdf.start_writing()\n        existing_pdf.write_header()\n        existing_pdf.write_comment(f\"created by Pillow {__version__} PDF driver\")\n    \n        #\n        # pages\n        ims = [im]\n        if save_all:\n            append_images = im.encoderinfo.get(\"append_images\", [])\n            for append_im in append_images:\n                append_im.encoderinfo = im.encoderinfo.copy()\n                ims.append(append_im)\n        number_of_pages = 0\n        image_refs = []\n        page_refs = []\n        contents_refs = []\n        for im in ims:\n            im_number_of_pages = 1\n            if save_all:\n                try:\n                    im_number_of_pages = im.n_frames\n                except AttributeError:\n                    # Image format does not have n_frames.\n                    # It is a single frame image\n                    pass\n            number_of_pages += im_number_of_pages\n            for i in range(im_number_of_pages):\n                image_refs.append(existing_pdf.next_object_id(0))\n                page_refs.append(existing_pdf.next_object_id(0))\n                contents_refs.append(existing_pdf.next_object_id(0))\n                existing_pdf.pages.append(page_refs[-1])\n    \n        #\n        # catalog and list of pages\n        existing_pdf.write_catalog()\n    \n        page_number = 0\n        for im_sequence in ims:\n            im_pages = ImageSequence.Iterator(im_sequence) if save_all else [im_sequence]\n            for im in im_pages:\n>               procset = _write_image(im, filename, existing_pdfs, image_refs)\n\u001b[1m\u001b[31mE               NameError: name 'existing_pdfs' is not defined\u001b[0m\n\n\u001b[1m\u001b[31msrc/PIL/PdfImagePlugin.py\u001b[0m:246: NameError\n\u001b[31m\u001b[1m________________________________ test_save[RGB] ________________________________\u001b[0m\n\ntmp_path = PosixPath('/tmp/pytest-of-gcpuser/pytest-509/test_save_RGB_0')\nmode = 'RGB'\n\n    @pytest.mark.parametrize(\"mode\", (\"L\", \"P\", \"RGB\", \"CMYK\"))\n    def test_save(tmp_path, mode):\n>       helper_save_as_pdf(tmp_path, mode)\n\n\u001b[1m\u001b[31mr2e_tests/test_1.py\u001b[0m:42: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\u001b[1m\u001b[31mr2e_tests/test_1.py\u001b[0m:20: in helper_save_as_pdf\n    im.save(outfile, **kwargs)\n\u001b[1m\u001b[31msrc/PIL/Image.py\u001b[0m:2416: in save\n    save_handler(self, fp, filename)\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\nim = <PIL.Image.Image image mode=RGB size=128x128 at 0x72FB807651F0>\nfp = <_io.BufferedRandom name='/tmp/pytest-of-gcpuser/pytest-509/test_save_RGB_0/temp_RGB.pdf'>\nfilename = '/tmp/pytest-of-gcpuser/pytest-509/test_save_RGB_0/temp_RGB.pdf'\nsave_all = False\n\n    def _save(im, fp, filename, save_all=False):\n        is_appending = im.encoderinfo.get(\"append\", False)\n        if is_appending:\n            existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode=\"r+b\")\n        else:\n            existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode=\"w+b\")\n    \n        dpi = im.encoderinfo.get(\"dpi\")\n        if dpi:\n            x_resolution = dpi[0]\n            y_resolution = dpi[1]\n        else:\n            x_resolution = y_resolution = im.encoderinfo.get(\"resolution\", 72.0)\n    \n        info = {\n            \"title\": None\n            if is_appending\n            else os.path.splitext(os.path.basename(filename))[0],\n            \"author\": None,\n            \"subject\": None,\n            \"keywords\": None,\n            \"creator\": None,\n            \"producer\": None,\n            \"creationDate\": None if is_appending else time.gmtime(),\n            \"modDate\": None if is_appending else time.gmtime(),\n        }\n        for k, default in info.items():\n            v = im.encoderinfo.get(k) if k in im.encoderinfo else default\n            if v:\n                existing_pdf.info[k[0].upper() + k[1:]] = v\n    \n        #\n        # make sure image data is available\n        im.load()\n    \n        existing_pdf.start_writing()\n        existing_pdf.write_header()\n        existing_pdf.write_comment(f\"created by Pillow {__version__} PDF driver\")\n    \n        #\n        # pages\n        ims = [im]\n        if save_all:\n            append_images = im.encoderinfo.get(\"append_images\", [])\n            for append_im in append_images:\n                append_im.encoderinfo = im.encoderinfo.copy()\n                ims.append(append_im)\n        number_of_pages = 0\n        image_refs = []\n        page_refs = []\n        contents_refs = []\n        for im in ims:\n            im_number_of_pages = 1\n            if save_all:\n                try:\n                    im_number_of_pages = im.n_frames\n                except AttributeError:\n                    # Image format does not have n_frames.\n                    # It is a single frame image\n                    pass\n            number_of_pages += im_number_of_pages\n            for i in range(im_number_of_pages):\n                image_refs.append(existing_pdf.next_object_id(0))\n                page_refs.append(existing_pdf.next_object_id(0))\n                contents_refs.append(existing_pdf.next_object_id(0))\n                existing_pdf.pages.append(page_refs[-1])\n    \n        #\n        # catalog and list of pages\n        existing_pdf.write_catalog()\n    \n        page_number = 0\n        for im_sequence in ims:\n            im_pages = ImageSequence.Iterator(im_sequence) if save_all else [im_sequence]\n            for im in im_pages:\n>               procset = _write_image(im, filename, existing_pdfs, image_refs)\n\u001b[1m\u001b[31mE               NameError: name 'existing_pdfs' is not defined\u001b[0m\n\n\u001b[1m\u001b[31msrc/PIL/PdfImagePlugin.py\u001b[0m:246: NameError\n\u001b[31m\u001b[1m_______________________________ test_save[CMYK] ________________________________\u001b[0m\n\ntmp_path = PosixPath('/tmp/pytest-of-gcpuser/pytest-509/test_save_CMYK_0')\nmode = 'CMYK'\n\n    @pytest.mark.parametrize(\"mode\", (\"L\", \"P\", \"RGB\", \"CMYK\"))\n    def test_save(tmp_path, mode):\n>       helper_save_as_pdf(tmp_path, mode)\n\n\u001b[1m\u001b[31mr2e_tests/test_1.py\u001b[0m:42: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\u001b[1m\u001b[31mr2e_tests/test_1.py\u001b[0m:20: in helper_save_as_pdf\n    im.save(outfile, **kwargs)\n\u001b[1m\u001b[31msrc/PIL/Image.py\u001b[0m:2416: in save\n    save_handler(self, fp, filename)\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\nim = <PIL.Image.Image image mode=CMYK size=128x128 at 0x72FB808102E0>\nfp = <_io.BufferedRandom name='/tmp/pytest-of-gcpuser/pytest-509/test_save_CMYK_0/temp_CMYK.pdf'>\nfilename = '/tmp/pytest-of-gcpuser/pytest-509/test_save_CMYK_0/temp_CMYK.pdf'\nsave_all = False\n\n    def _save(im, fp, filename, save_all=False):\n        is_appending = im.encoderinfo.get(\"append\", False)\n        if is_appending:\n            existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode=\"r+b\")\n        else:\n            existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode=\"w+b\")\n    \n        dpi = im.encoderinfo.get(\"dpi\")\n        if dpi:\n            x_resolution = dpi[0]\n            y_resolution = dpi[1]\n        else:\n            x_resolution = y_resolution = im.encoderinfo.get(\"resolution\", 72.0)\n    \n        info = {\n            \"title\": None\n            if is_appending\n            else os.path.splitext(os.path.basename(filename))[0],\n            \"author\": None,\n            \"subject\": None,\n            \"keywords\": None,\n            \"creator\": None,\n            \"producer\": None,\n            \"creationDate\": None if is_appending else time.gmtime(),\n            \"modDate\": None if is_appending else time.gmtime(),\n        }\n        for k, default in info.items():\n            v = im.encoderinfo.get(k) if k in im.encoderinfo else default\n            if v:\n                existing_pdf.info[k[0].upper() + k[1:]] = v\n    \n        #\n        # make sure image data is available\n        im.load()\n    \n        existing_pdf.start_writing()\n        existing_pdf.write_header()\n        existing_pdf.write_comment(f\"created by Pillow {__version__} PDF driver\")\n    \n        #\n        # pages\n        ims = [im]\n        if save_all:\n            append_images = im.encoderinfo.get(\"append_images\", [])\n            for append_im in append_images:\n                append_im.encoderinfo = im.encoderinfo.copy()\n                ims.append(append_im)\n        number_of_pages = 0\n        image_refs = []\n        page_refs = []\n        contents_refs = []\n        for im in ims:\n            im_number_of_pages = 1\n            if save_all:\n                try:\n                    im_number_of_pages = im.n_frames\n                except AttributeError:\n                    # Image format does not have n_frames.\n                    # It is a single frame image\n                    pass\n            number_of_pages += im_number_of_pages\n            for i in range(im_number_of_pages):\n                image_refs.append(existing_pdf.next_object_id(0))\n                page_refs.append(existing_pdf.next_object_id(0))\n                contents_refs.append(existing_pdf.next_object_id(0))\n                existing_pdf.pages.append(page_refs[-1])\n    \n        #\n        # catalog and list of pages\n        existing_pdf.write_catalog()\n    \n        page_number = 0\n        for im_sequence in ims:\n            im_pages = ImageSequence.Iterator(im_sequence) if save_all else [im_sequence]\n            for im in im_pages:\n>               procset = _write_image(im, filename, existing_pdfs, image_refs)\n\u001b[1m\u001b[31mE               NameError: name 'existing_pdfs' is not defined\u001b[0m\n\n\u001b[1m\u001b[31msrc/PIL/PdfImagePlugin.py\u001b[0m:246: NameError\n\u001b[31m\u001b[1m_________________________________ test_p_alpha _________________________________\u001b[0m\n\ntmp_path = PosixPath('/tmp/pytest-of-gcpuser/pytest-509/test_p_alpha0')\n\n    def test_p_alpha(tmp_path):\n        # Arrange\n        outfile = str(tmp_path / \"temp.pdf\")\n        with Image.open(\"Tests/images/pil123p.png\") as im:\n            assert im.mode == \"P\"\n            assert isinstance(im.info[\"transparency\"], bytes)\n    \n            # Act\n>           im.save(outfile)\n\n\u001b[1m\u001b[31mr2e_tests/test_1.py\u001b[0m:59: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\u001b[1m\u001b[31msrc/PIL/Image.py\u001b[0m:2416: in save\n    save_handler(self, fp, filename)\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\nim = <PIL.PngImagePlugin.PngImageFile image mode=P size=162x150 at 0x72FB80817F70>\nfp = <_io.BufferedRandom name='/tmp/pytest-of-gcpuser/pytest-509/test_p_alpha0/temp.pdf'>\nfilename = '/tmp/pytest-of-gcpuser/pytest-509/test_p_alpha0/temp.pdf'\nsave_all = False\n\n    def _save(im, fp, filename, save_all=False):\n        is_appending = im.encoderinfo.get(\"append\", False)\n        if is_appending:\n            existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode=\"r+b\")\n        else:\n            existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode=\"w+b\")\n    \n        dpi = im.encoderinfo.get(\"dpi\")\n        if dpi:\n            x_resolution = dpi[0]\n            y_resolution = dpi[1]\n        else:\n            x_resolution = y_resolution = im.encoderinfo.get(\"resolution\", 72.0)\n    \n        info = {\n            \"title\": None\n            if is_appending\n            else os.path.splitext(os.path.basename(filename))[0],\n            \"author\": None,\n            \"subject\": None,\n            \"keywords\": None,\n            \"creator\": None,\n            \"producer\": None,\n            \"creationDate\": None if is_appending else time.gmtime(),\n            \"modDate\": None if is_appending else time.gmtime(),\n        }\n        for k, default in info.items():\n            v = im.encoderinfo.get(k) if k in im.encoderinfo else default\n            if v:\n                existing_pdf.info[k[0].upper() + k[1:]] = v\n    \n        #\n        # make sure image data is available\n        im.load()\n    \n        existing_pdf.start_writing()\n        existing_pdf.write_header()\n        existing_pdf.write_comment(f\"created by Pillow {__version__} PDF driver\")\n    \n        #\n        # pages\n        ims = [im]\n        if save_all:\n            append_images = im.encoderinfo.get(\"append_images\", [])\n            for append_im in append_images:\n                append_im.encoderinfo = im.encoderinfo.copy()\n                ims.append(append_im)\n        number_of_pages = 0\n        image_refs = []\n        page_refs = []\n        contents_refs = []\n        for im in ims:\n            im_number_of_pages = 1\n            if save_all:\n                try:\n                    im_number_of_pages = im.n_frames\n                except AttributeError:\n                    # Image format does not have n_frames.\n                    # It is a single frame image\n                    pass\n            number_of_pages += im_number_of_pages\n            for i in range(im_number_of_pages):\n                image_refs.append(existing_pdf.next_object_id(0))\n                page_refs.append(existing_pdf.next_object_id(0))\n                contents_refs.append(existing_pdf.next_object_id(0))\n                existing_pdf.pages.append(page_refs[-1])\n    \n        #\n        # catalog and list of pages\n        existing_pdf.write_catalog()\n    \n        page_number = 0\n        for im_sequence in ims:\n            im_pages = ImageSequence.Iterator(im_sequence) if save_all else [im_sequence]\n            for im in im_pages:\n>               procset = _write_image(im, filename, existing_pdfs, image_refs)\n\u001b[1m\u001b[31mE               NameError: name 'existing_pdfs' is not defined\u001b[0m\n\n\u001b[1m\u001b[31msrc/PIL/PdfImagePlugin.py\u001b[0m:246: NameError\n\u001b[31m\u001b[1m_______________________________ test_monochrome ________________________________\u001b[0m\n\ntmp_path = PosixPath('/tmp/pytest-of-gcpuser/pytest-509/test_monochrome0')\n\n    def test_monochrome(tmp_path):\n        # Arrange\n        mode = \"1\"\n    \n        # Act / Assert\n>       outfile = helper_save_as_pdf(tmp_path, mode)\n\n\u001b[1m\u001b[31mr2e_tests/test_1.py\u001b[0m:72: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\u001b[1m\u001b[31mr2e_tests/test_1.py\u001b[0m:20: in helper_save_as_pdf\n    im.save(outfile, **kwargs)\n\u001b[1m\u001b[31msrc/PIL/Image.py\u001b[0m:2416: in save\n    save_handler(self, fp, filename)\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\nim = <PIL.Image.Image image mode=1 size=128x128 at 0x72FB80665AF0>\nfp = <_io.BufferedRandom name='/tmp/pytest-of-gcpuser/pytest-509/test_monochrome0/temp_1.pdf'>\nfilename = '/tmp/pytest-of-gcpuser/pytest-509/test_monochrome0/temp_1.pdf'\nsave_all = False\n\n    def _save(im, fp, filename, save_all=False):\n        is_appending = im.encoderinfo.get(\"append\", False)\n        if is_appending:\n            existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode=\"r+b\")\n        else:\n            existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode=\"w+b\")\n    \n        dpi = im.encoderinfo.get(\"dpi\")\n        if dpi:\n            x_resolution = dpi[0]\n            y_resolution = dpi[1]\n        else:\n            x_resolution = y_resolution = im.encoderinfo.get(\"resolution\", 72.0)\n    \n        info = {\n            \"title\": None\n            if is_appending\n            else os.path.splitext(os.path.basename(filename))[0],\n            \"author\": None,\n            \"subject\": None,\n            \"keywords\": None,\n            \"creator\": None,\n            \"producer\": None,\n            \"creationDate\": None if is_appending else time.gmtime(),\n            \"modDate\": None if is_appending else time.gmtime(),\n        }\n        for k, default in info.items():\n            v = im.encoderinfo.get(k) if k in im.encoderinfo else default\n            if v:\n                existing_pdf.info[k[0].upper() + k[1:]] = v\n    \n        #\n        # make sure image data is available\n        im.load()\n    \n        existing_pdf.start_writing()\n        existing_pdf.write_header()\n        existing_pdf.write_comment(f\"created by Pillow {__version__} PDF driver\")\n    \n        #\n        # pages\n        ims = [im]\n        if save_all:\n            append_images = im.encoderinfo.get(\"append_images\", [])\n            for append_im in append_images:\n                append_im.encoderinfo = im.encoderinfo.copy()\n                ims.append(append_im)\n        number_of_pages = 0\n        image_refs = []\n        page_refs = []\n        contents_refs = []\n        for im in ims:\n            im_number_of_pages = 1\n            if save_all:\n                try:\n                    im_number_of_pages = im.n_frames\n                except AttributeError:\n                    # Image format does not have n_frames.\n                    # It is a single frame image\n                    pass\n            number_of_pages += im_number_of_pages\n            for i in range(im_number_of_pages):\n                image_refs.append(existing_pdf.next_object_id(0))\n                page_refs.append(existing_pdf.next_object_id(0))\n                contents_refs.append(existing_pdf.next_object_id(0))\n                existing_pdf.pages.append(page_refs[-1])\n    \n        #\n        # catalog and list of pages\n        existing_pdf.write_catalog()\n    \n        page_number = 0\n        for im_sequence in ims:\n            im_pages = ImageSequence.Iterator(im_sequence) if save_all else [im_sequence]\n            for im in im_pages:\n>               procset = _write_image(im, filename, existing_pdfs, image_refs)\n\u001b[1m\u001b[31mE               NameError: name 'existing_pdfs' is not defined\u001b[0m\n\n\u001b[1m\u001b[31msrc/PIL/PdfImagePlugin.py\u001b[0m:246: NameError\n\u001b[31m\u001b[1m____________________________ test_unsupported_mode _____________________________\u001b[0m\n\ntmp_path = PosixPath('/tmp/pytest-of-gcpuser/pytest-509/test_unsupported_mode0')\n\n    def test_unsupported_mode(tmp_path):\n        im = hopper(\"PA\")\n        outfile = str(tmp_path / \"temp_PA.pdf\")\n    \n        with pytest.raises(ValueError):\n>           im.save(outfile)\n\n\u001b[1m\u001b[31mr2e_tests/test_1.py\u001b[0m:81: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\u001b[1m\u001b[31msrc/PIL/Image.py\u001b[0m:2416: in save\n    save_handler(self, fp, filename)\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\nim = <PIL.Image.Image image mode=PA size=128x128 at 0x72FB813A9550>\nfp = <_io.BufferedRandom name='/tmp/pytest-of-gcpuser/pytest-509/test_unsupported_mode0/temp_PA.pdf'>\nfilename = '/tmp/pytest-of-gcpuser/pytest-509/test_unsupported_mode0/temp_PA.pdf'\nsave_all = False\n\n    def _save(im, fp, filename, save_all=False):\n        is_appending = im.encoderinfo.get(\"append\", False)\n        if is_appending:\n            existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode=\"r+b\")\n        else:\n            existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode=\"w+b\")\n    \n        dpi = im.encoderinfo.get(\"dpi\")\n        if dpi:\n            x_resolution = dpi[0]\n            y_resolution = dpi[1]\n        else:\n            x_resolution = y_resolution = im.encoderinfo.get(\"resolution\", 72.0)\n    \n        info = {\n            \"title\": None\n            if is_appending\n            else os.path.splitext(os.path.basename(filename))[0],\n            \"author\": None,\n            \"subject\": None,\n            \"keywords\": None,\n            \"creator\": None,\n            \"producer\": None,\n            \"creationDate\": None if is_appending else time.gmtime(),\n            \"modDate\": None if is_appending else time.gmtime(),\n        }\n        for k, default in info.items():\n            v = im.encoderinfo.get(k) if k in im.encoderinfo else default\n            if v:\n                existing_pdf.info[k[0].upper() + k[1:]] = v\n    \n        #\n        # make sure image data is available\n        im.load()\n    \n        existing_pdf.start_writing()\n        existing_pdf.write_header()\n        existing_pdf.write_comment(f\"created by Pillow {__version__} PDF driver\")\n    \n        #\n        # pages\n        ims = [im]\n        if save_all:\n            append_images = im.encoderinfo.get(\"append_images\", [])\n            for append_im in append_images:\n                append_im.encoderinfo = im.encoderinfo.copy()\n                ims.append(append_im)\n        number_of_pages = 0\n        image_refs = []\n        page_refs = []\n        contents_refs = []\n        for im in ims:\n            im_number_of_pages = 1\n            if save_all:\n                try:\n                    im_number_of_pages = im.n_frames\n                except AttributeError:\n                    # Image format does not have n_frames.\n                    # It is a single frame image\n                    pass\n            number_of_pages += im_number_of_pages\n            for i in range(im_number_of_pages):\n                image_refs.append(existing_pdf.next_object_id(0))\n                page_refs.append(existing_pdf.next_object_id(0))\n                contents_refs.append(existing_pdf.next_object_id(0))\n                existing_pdf.pages.append(page_refs[-1])\n    \n        #\n        # catalog and list of pages\n        existing_pdf.write_catalog()\n    \n        page_number = 0\n        for im_sequence in ims:\n            im_pages = ImageSequence.Iterator(im_sequence) if save_all else [im_sequence]\n            for im in im_pages:\n>               procset = _write_image(im, filename, existing_pdfs, image_refs)\n\u001b[1m\u001b[31mE               NameError: name 'existing_pdfs' is not defined\u001b[0m\n\n\u001b[1m\u001b[31msrc/PIL/PdfImagePlugin.py\u001b[0m:246: NameError\n\u001b[31m\u001b[1m_______________________________ test_resolution ________________________________\u001b[0m\n\ntmp_path = PosixPath('/tmp/pytest-of-gcpuser/pytest-509/test_resolution0')\n\n    def test_resolution(tmp_path):\n        im = hopper()\n    \n        outfile = str(tmp_path / \"temp.pdf\")\n>       im.save(outfile, resolution=150)\n\n\u001b[1m\u001b[31mr2e_tests/test_1.py\u001b[0m:88: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\u001b[1m\u001b[31msrc/PIL/Image.py\u001b[0m:2416: in save\n    save_handler(self, fp, filename)\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\nim = <PIL.PpmImagePlugin.PpmImageFile image mode=RGB size=128x128 at 0x72FB806656A0>\nfp = <_io.BufferedRandom name='/tmp/pytest-of-gcpuser/pytest-509/test_resolution0/temp.pdf'>\nfilename = '/tmp/pytest-of-gcpuser/pytest-509/test_resolution0/temp.pdf'\nsave_all = False\n\n    def _save(im, fp, filename, save_all=False):\n        is_appending = im.encoderinfo.get(\"append\", False)\n        if is_appending:\n            existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode=\"r+b\")\n        else:\n            existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode=\"w+b\")\n    \n        dpi = im.encoderinfo.get(\"dpi\")\n        if dpi:\n            x_resolution = dpi[0]\n            y_resolution = dpi[1]\n        else:\n            x_resolution = y_resolution = im.encoderinfo.get(\"resolution\", 72.0)\n    \n        info = {\n            \"title\": None\n            if is_appending\n            else os.path.splitext(os.path.basename(filename))[0],\n            \"author\": None,\n            \"subject\": None,\n            \"keywords\": None,\n            \"creator\": None,\n            \"producer\": None,\n            \"creationDate\": None if is_appending else time.gmtime(),\n            \"modDate\": None if is_appending else time.gmtime(),\n        }\n        for k, default in info.items():\n            v = im.encoderinfo.get(k) if k in im.encoderinfo else default\n            if v:\n                existing_pdf.info[k[0].upper() + k[1:]] = v\n    \n        #\n        # make sure image data is available\n        im.load()\n    \n        existing_pdf.start_writing()\n        existing_pdf.write_header()\n        existing_pdf.write_comment(f\"created by Pillow {__version__} PDF driver\")\n    \n        #\n        # pages\n        ims = [im]\n        if save_all:\n            append_images = im.encoderinfo.get(\"append_images\", [])\n            for append_im in append_images:\n                append_im.encoderinfo = im.encoderinfo.copy()\n                ims.append(append_im)\n        number_of_pages = 0\n        image_refs = []\n        page_refs = []\n        contents_refs = []\n        for im in ims:\n            im_number_of_pages = 1\n            if save_all:\n                try:\n                    im_number_of_pages = im.n_frames\n                except AttributeError:\n                    # Image format does not have n_frames.\n                    # It is a single frame image\n                    pass\n            number_of_pages += im_number_of_pages\n            for i in range(im_number_of_pages):\n                image_refs.append(existing_pdf.next_object_id(0))\n                page_refs.append(existing_pdf.next_object_id(0))\n                contents_refs.append(existing_pdf.next_object_id(0))\n                existing_pdf.pages.append(page_refs[-1])\n    \n        #\n        # catalog and list of pages\n        existing_pdf.write_catalog()\n    \n        page_number = 0\n        for im_sequence in ims:\n            im_pages = ImageSequence.Iterator(im_sequence) if save_all else [im_sequence]\n            for im in im_pages:\n>               procset = _write_image(im, filename, existing_pdfs, image_refs)\n\u001b[1m\u001b[31mE               NameError: name 'existing_pdfs' is not defined\u001b[0m\n\n\u001b[1m\u001b[31msrc/PIL/PdfImagePlugin.py\u001b[0m:246: NameError\n\u001b[31m\u001b[1m______________________________ test_dpi[params0] _______________________________\u001b[0m\n\nparams = {'dpi': (75, 150)}\ntmp_path = PosixPath('/tmp/pytest-of-gcpuser/pytest-509/test_dpi_params0_0')\n\n    @pytest.mark.parametrize(\n        \"params\",\n        (\n            {\"dpi\": (75, 150)},\n            {\"dpi\": (75, 150), \"resolution\": 200},\n        ),\n    )\n    def test_dpi(params, tmp_path):\n        im = hopper()\n    \n        outfile = str(tmp_path / \"temp.pdf\")\n>       im.save(outfile, **params)\n\n\u001b[1m\u001b[31mr2e_tests/test_1.py\u001b[0m:116: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\u001b[1m\u001b[31msrc/PIL/Image.py\u001b[0m:2416: in save\n    save_handler(self, fp, filename)\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\nim = <PIL.PpmImagePlugin.PpmImageFile image mode=RGB size=128x128 at 0x72FB80817B80>\nfp = <_io.BufferedRandom name='/tmp/pytest-of-gcpuser/pytest-509/test_dpi_params0_0/temp.pdf'>\nfilename = '/tmp/pytest-of-gcpuser/pytest-509/test_dpi_params0_0/temp.pdf'\nsave_all = False\n\n    def _save(im, fp, filename, save_all=False):\n        is_appending = im.encoderinfo.get(\"append\", False)\n        if is_appending:\n            existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode=\"r+b\")\n        else:\n            existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode=\"w+b\")\n    \n        dpi = im.encoderinfo.get(\"dpi\")\n        if dpi:\n            x_resolution = dpi[0]\n            y_resolution = dpi[1]\n        else:\n            x_resolution = y_resolution = im.encoderinfo.get(\"resolution\", 72.0)\n    \n        info = {\n            \"title\": None\n            if is_appending\n            else os.path.splitext(os.path.basename(filename))[0],\n            \"author\": None,\n            \"subject\": None,\n            \"keywords\": None,\n            \"creator\": None,\n            \"producer\": None,\n            \"creationDate\": None if is_appending else time.gmtime(),\n            \"modDate\": None if is_appending else time.gmtime(),\n        }\n        for k, default in info.items():\n            v = im.encoderinfo.get(k) if k in im.encoderinfo else default\n            if v:\n                existing_pdf.info[k[0].upper() + k[1:]] = v\n    \n        #\n        # make sure image data is available\n        im.load()\n    \n        existing_pdf.start_writing()\n        existing_pdf.write_header()\n        existing_pdf.write_comment(f\"created by Pillow {__version__} PDF driver\")\n    \n        #\n        # pages\n        ims = [im]\n        if save_all:\n            append_images = im.encoderinfo.get(\"append_images\", [])\n            for append_im in append_images:\n                append_im.encoderinfo = im.encoderinfo.copy()\n                ims.append(append_im)\n        number_of_pages = 0\n        image_refs = []\n        page_refs = []\n        contents_refs = []\n        for im in ims:\n            im_number_of_pages = 1\n            if save_all:\n                try:\n                    im_number_of_pages = im.n_frames\n                except AttributeError:\n                    # Image format does not have n_frames.\n                    # It is a single frame image\n                    pass\n            number_of_pages += im_number_of_pages\n            for i in range(im_number_of_pages):\n                image_refs.append(existing_pdf.next_object_id(0))\n                page_refs.append(existing_pdf.next_object_id(0))\n                contents_refs.append(existing_pdf.next_object_id(0))\n                existing_pdf.pages.append(page_refs[-1])\n    \n        #\n        # catalog and list of pages\n        existing_pdf.write_catalog()\n    \n        page_number = 0\n        for im_sequence in ims:\n            im_pages = ImageSequence.Iterator(im_sequence) if save_all else [im_sequence]\n            for im in im_pages:\n>               procset = _write_image(im, filename, existing_pdfs, image_refs)\n\u001b[1m\u001b[31mE               NameError: name 'existing_pdfs' is not defined\u001b[0m\n\n\u001b[1m\u001b[31msrc/PIL/PdfImagePlugin.py\u001b[0m:246: NameError\n\u001b[31m\u001b[1m______________________________ test_dpi[params1] _______________________________\u001b[0m\n\nparams = {'dpi': (75, 150), 'resolution': 200}\ntmp_path = PosixPath('/tmp/pytest-of-gcpuser/pytest-509/test_dpi_params1_0')\n\n    @pytest.mark.parametrize(\n        \"params\",\n        (\n            {\"dpi\": (75, 150)},\n            {\"dpi\": (75, 150), \"resolution\": 200},\n        ),\n    )\n    def test_dpi(params, tmp_path):\n        im = hopper()\n    \n        outfile = str(tmp_path / \"temp.pdf\")\n>       im.save(outfile, **params)\n\n\u001b[1m\u001b[31mr2e_tests/test_1.py\u001b[0m:116: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\u001b[1m\u001b[31msrc/PIL/Image.py\u001b[0m:2416: in save\n    save_handler(self, fp, filename)\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\nim = <PIL.PpmImagePlugin.PpmImageFile image mode=RGB size=128x128 at 0x72FB80843AC0>\nfp = <_io.BufferedRandom name='/tmp/pytest-of-gcpuser/pytest-509/test_dpi_params1_0/temp.pdf'>\nfilename = '/tmp/pytest-of-gcpuser/pytest-509/test_dpi_params1_0/temp.pdf'\nsave_all = False\n\n    def _save(im, fp, filename, save_all=False):\n        is_appending = im.encoderinfo.get(\"append\", False)\n        if is_appending:\n            existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode=\"r+b\")\n        else:\n            existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode=\"w+b\")\n    \n        dpi = im.encoderinfo.get(\"dpi\")\n        if dpi:\n            x_resolution = dpi[0]\n            y_resolution = dpi[1]\n        else:\n            x_resolution = y_resolution = im.encoderinfo.get(\"resolution\", 72.0)\n    \n        info = {\n            \"title\": None\n            if is_appending\n            else os.path.splitext(os.path.basename(filename))[0],\n            \"author\": None,\n            \"subject\": None,\n            \"keywords\": None,\n            \"creator\": None,\n            \"producer\": None,\n            \"creationDate\": None if is_appending else time.gmtime(),\n            \"modDate\": None if is_appending else time.gmtime(),\n        }\n        for k, default in info.items():\n            v = im.encoderinfo.get(k) if k in im.encoderinfo else default\n            if v:\n                existing_pdf.info[k[0].upper() + k[1:]] = v\n    \n        #\n        # make sure image data is available\n        im.load()\n    \n        existing_pdf.start_writing()\n        existing_pdf.write_header()\n        existing_pdf.write_comment(f\"created by Pillow {__version__} PDF driver\")\n    \n        #\n        # pages\n        ims = [im]\n        if save_all:\n            append_images = im.encoderinfo.get(\"append_images\", [])\n            for append_im in append_images:\n                append_im.encoderinfo = im.encoderinfo.copy()\n                ims.append(append_im)\n        number_of_pages = 0\n        image_refs = []\n        page_refs = []\n        contents_refs = []\n        for im in ims:\n            im_number_of_pages = 1\n            if save_all:\n                try:\n                    im_number_of_pages = im.n_frames\n                except AttributeError:\n                    # Image format does not have n_frames.\n                    # It is a single frame image\n                    pass\n            number_of_pages += im_number_of_pages\n            for i in range(im_number_of_pages):\n                image_refs.append(existing_pdf.next_object_id(0))\n                page_refs.append(existing_pdf.next_object_id(0))\n                contents_refs.append(existing_pdf.next_object_id(0))\n                existing_pdf.pages.append(page_refs[-1])\n    \n        #\n        # catalog and list of pages\n        existing_pdf.write_catalog()\n    \n        page_number = 0\n        for im_sequence in ims:\n            im_pages = ImageSequence.Iterator(im_sequence) if save_all else [im_sequence]\n            for im in im_pages:\n>               procset = _write_image(im, filename, existing_pdfs, image_refs)\n\u001b[1m\u001b[31mE               NameError: name 'existing_pdfs' is not defined\u001b[0m\n\n\u001b[1m\u001b[31msrc/PIL/PdfImagePlugin.py\u001b[0m:246: NameError\n\u001b[31m\u001b[1m________________________________ test_save_all _________________________________\u001b[0m\n\ntmp_path = PosixPath('/tmp/pytest-of-gcpuser/pytest-509/test_save_all0')\n\n    @mark_if_feature_version(\n        pytest.mark.valgrind_known_error, \"libjpeg_turbo\", \"2.0\", reason=\"Known Failing\"\n    )\n    def test_save_all(tmp_path):\n        # Single frame image\n>       helper_save_as_pdf(tmp_path, \"RGB\", save_all=True)\n\n\u001b[1m\u001b[31mr2e_tests/test_1.py\u001b[0m:138: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\u001b[1m\u001b[31mr2e_tests/test_1.py\u001b[0m:20: in helper_save_as_pdf\n    im.save(outfile, **kwargs)\n\u001b[1m\u001b[31msrc/PIL/Image.py\u001b[0m:2416: in save\n    save_handler(self, fp, filename)\n\u001b[1m\u001b[31msrc/PIL/PdfImagePlugin.py\u001b[0m:42: in _save_all\n    _save(im, fp, filename, save_all=True)\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\nim = <PIL.Image.Image image mode=RGB size=128x128 at 0x72FB8081E160>\nfp = <_io.BufferedRandom name='/tmp/pytest-of-gcpuser/pytest-509/test_save_all0/temp_RGB.pdf'>\nfilename = '/tmp/pytest-of-gcpuser/pytest-509/test_save_all0/temp_RGB.pdf'\nsave_all = True\n\n    def _save(im, fp, filename, save_all=False):\n        is_appending = im.encoderinfo.get(\"append\", False)\n        if is_appending:\n            existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode=\"r+b\")\n        else:\n            existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode=\"w+b\")\n    \n        dpi = im.encoderinfo.get(\"dpi\")\n        if dpi:\n            x_resolution = dpi[0]\n            y_resolution = dpi[1]\n        else:\n            x_resolution = y_resolution = im.encoderinfo.get(\"resolution\", 72.0)\n    \n        info = {\n            \"title\": None\n            if is_appending\n            else os.path.splitext(os.path.basename(filename))[0],\n            \"author\": None,\n            \"subject\": None,\n            \"keywords\": None,\n            \"creator\": None,\n            \"producer\": None,\n            \"creationDate\": None if is_appending else time.gmtime(),\n            \"modDate\": None if is_appending else time.gmtime(),\n        }\n        for k, default in info.items():\n            v = im.encoderinfo.get(k) if k in im.encoderinfo else default\n            if v:\n                existing_pdf.info[k[0].upper() + k[1:]] = v\n    \n        #\n        # make sure image data is available\n        im.load()\n    \n        existing_pdf.start_writing()\n        existing_pdf.write_header()\n        existing_pdf.write_comment(f\"created by Pillow {__version__} PDF driver\")\n    \n        #\n        # pages\n        ims = [im]\n        if save_all:\n            append_images = im.encoderinfo.get(\"append_images\", [])\n            for append_im in append_images:\n                append_im.encoderinfo = im.encoderinfo.copy()\n                ims.append(append_im)\n        number_of_pages = 0\n        image_refs = []\n        page_refs = []\n        contents_refs = []\n        for im in ims:\n            im_number_of_pages = 1\n            if save_all:\n                try:\n                    im_number_of_pages = im.n_frames\n                except AttributeError:\n                    # Image format does not have n_frames.\n                    # It is a single frame image\n                    pass\n            number_of_pages += im_number_of_pages\n            for i in range(im_number_of_pages):\n                image_refs.append(existing_pdf.next_object_id(0))\n                page_refs.append(existing_pdf.next_object_id(0))\n                contents_refs.append(existing_pdf.next_object_id(0))\n                existing_pdf.pages.append(page_refs[-1])\n    \n        #\n        # catalog and list of pages\n        existing_pdf.write_catalog()\n    \n        page_number = 0\n        for im_sequence in ims:\n            im_pages = ImageSequence.Iterator(im_sequence) if save_all else [im_sequence]\n            for im in im_pages:\n>               procset = _write_image(im, filename, existing_pdfs, image_refs)\n\u001b[1m\u001b[31mE               NameError: name 'existing_pdfs' is not defined\u001b[0m\n\n\u001b[1m\u001b[31msrc/PIL/PdfImagePlugin.py\u001b[0m:246: NameError\n\u001b[31m\u001b[1m_________________________ test_multiframe_normal_save __________________________\u001b[0m\n\ntmp_path = PosixPath('/tmp/pytest-of-gcpuser/pytest-509/test_multiframe_normal_save0')\n\n    def test_multiframe_normal_save(tmp_path):\n        # Test saving a multiframe image without save_all\n        with Image.open(\"Tests/images/dispose_bgnd.gif\") as im:\n            outfile = str(tmp_path / \"temp.pdf\")\n>           im.save(outfile)\n\n\u001b[1m\u001b[31mr2e_tests/test_1.py\u001b[0m:176: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\u001b[1m\u001b[31msrc/PIL/Image.py\u001b[0m:2416: in save\n    save_handler(self, fp, filename)\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\nim = <PIL.GifImagePlugin.GifImageFile image mode=P size=100x100 at 0x72FB80752640>\nfp = <_io.BufferedRandom name='/tmp/pytest-of-gcpuser/pytest-509/test_multiframe_normal_save0/temp.pdf'>\nfilename = '/tmp/pytest-of-gcpuser/pytest-509/test_multiframe_normal_save0/temp.pdf'\nsave_all = False\n\n    def _save(im, fp, filename, save_all=False):\n        is_appending = im.encoderinfo.get(\"append\", False)\n        if is_appending:\n            existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode=\"r+b\")\n        else:\n            existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode=\"w+b\")\n    \n        dpi = im.encoderinfo.get(\"dpi\")\n        if dpi:\n            x_resolution = dpi[0]\n            y_resolution = dpi[1]\n        else:\n            x_resolution = y_resolution = im.encoderinfo.get(\"resolution\", 72.0)\n    \n        info = {\n            \"title\": None\n            if is_appending\n            else os.path.splitext(os.path.basename(filename))[0],\n            \"author\": None,\n            \"subject\": None,\n            \"keywords\": None,\n            \"creator\": None,\n            \"producer\": None,\n            \"creationDate\": None if is_appending else time.gmtime(),\n            \"modDate\": None if is_appending else time.gmtime(),\n        }\n        for k, default in info.items():\n            v = im.encoderinfo.get(k) if k in im.encoderinfo else default\n            if v:\n                existing_pdf.info[k[0].upper() + k[1:]] = v\n    \n        #\n        # make sure image data is available\n        im.load()\n    \n        existing_pdf.start_writing()\n        existing_pdf.write_header()\n        existing_pdf.write_comment(f\"created by Pillow {__version__} PDF driver\")\n    \n        #\n        # pages\n        ims = [im]\n        if save_all:\n            append_images = im.encoderinfo.get(\"append_images\", [])\n            for append_im in append_images:\n                append_im.encoderinfo = im.encoderinfo.copy()\n                ims.append(append_im)\n        number_of_pages = 0\n        image_refs = []\n        page_refs = []\n        contents_refs = []\n        for im in ims:\n            im_number_of_pages = 1\n            if save_all:\n                try:\n                    im_number_of_pages = im.n_frames\n                except AttributeError:\n                    # Image format does not have n_frames.\n                    # It is a single frame image\n                    pass\n            number_of_pages += im_number_of_pages\n            for i in range(im_number_of_pages):\n                image_refs.append(existing_pdf.next_object_id(0))\n                page_refs.append(existing_pdf.next_object_id(0))\n                contents_refs.append(existing_pdf.next_object_id(0))\n                existing_pdf.pages.append(page_refs[-1])\n    \n        #\n        # catalog and list of pages\n        existing_pdf.write_catalog()\n    \n        page_number = 0\n        for im_sequence in ims:\n            im_pages = ImageSequence.Iterator(im_sequence) if save_all else [im_sequence]\n            for im in im_pages:\n>               procset = _write_image(im, filename, existing_pdfs, image_refs)\n\u001b[1m\u001b[31mE               NameError: name 'existing_pdfs' is not defined\u001b[0m\n\n\u001b[1m\u001b[31msrc/PIL/PdfImagePlugin.py\u001b[0m:246: NameError\n\u001b[31m\u001b[1m________________________________ test_pdf_open _________________________________\u001b[0m\n\ntmp_path = PosixPath('/tmp/pytest-of-gcpuser/pytest-509/test_pdf_open0')\n\n    def test_pdf_open(tmp_path):\n        # fail on a buffer full of null bytes\n        with pytest.raises(PdfParser.PdfFormatError):\n            PdfParser.PdfParser(buf=bytearray(65536))\n    \n        # make an empty PDF object\n        with PdfParser.PdfParser() as empty_pdf:\n            assert len(empty_pdf.pages) == 0\n            assert len(empty_pdf.info) == 0\n            assert not empty_pdf.should_close_buf\n            assert not empty_pdf.should_close_file\n    \n        # make a PDF file\n>       pdf_filename = helper_save_as_pdf(tmp_path, \"RGB\")\n\n\u001b[1m\u001b[31mr2e_tests/test_1.py\u001b[0m:195: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\u001b[1m\u001b[31mr2e_tests/test_1.py\u001b[0m:20: in helper_save_as_pdf\n    im.save(outfile, **kwargs)\n\u001b[1m\u001b[31msrc/PIL/Image.py\u001b[0m:2416: in save\n    save_handler(self, fp, filename)\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\nim = <PIL.Image.Image image mode=RGB size=128x128 at 0x72FB80A63D90>\nfp = <_io.BufferedRandom name='/tmp/pytest-of-gcpuser/pytest-509/test_pdf_open0/temp_RGB.pdf'>\nfilename = '/tmp/pytest-of-gcpuser/pytest-509/test_pdf_open0/temp_RGB.pdf'\nsave_all = False\n\n    def _save(im, fp, filename, save_all=False):\n        is_appending = im.encoderinfo.get(\"append\", False)\n        if is_appending:\n            existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode=\"r+b\")\n        else:\n            existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode=\"w+b\")\n    \n        dpi = im.encoderinfo.get(\"dpi\")\n        if dpi:\n            x_resolution = dpi[0]\n            y_resolution = dpi[1]\n        else:\n            x_resolution = y_resolution = im.encoderinfo.get(\"resolution\", 72.0)\n    \n        info = {\n            \"title\": None\n            if is_appending\n            else os.path.splitext(os.path.basename(filename))[0],\n            \"author\": None,\n            \"subject\": None,\n            \"keywords\": None,\n            \"creator\": None,\n            \"producer\": None,\n            \"creationDate\": None if is_appending else time.gmtime(),\n            \"modDate\": None if is_appending else time.gmtime(),\n        }\n        for k, default in info.items():\n            v = im.encoderinfo.get(k) if k in im.encoderinfo else default\n            if v:\n                existing_pdf.info[k[0].upper() + k[1:]] = v\n    \n        #\n        # make sure image data is available\n        im.load()\n    \n        existing_pdf.start_writing()\n        existing_pdf.write_header()\n        existing_pdf.write_comment(f\"created by Pillow {__version__} PDF driver\")\n    \n        #\n        # pages\n        ims = [im]\n        if save_all:\n            append_images = im.encoderinfo.get(\"append_images\", [])\n            for append_im in append_images:\n                append_im.encoderinfo = im.encoderinfo.copy()\n                ims.append(append_im)\n        number_of_pages = 0\n        image_refs = []\n        page_refs = []\n        contents_refs = []\n        for im in ims:\n            im_number_of_pages = 1\n            if save_all:\n                try:\n                    im_number_of_pages = im.n_frames\n                except AttributeError:\n                    # Image format does not have n_frames.\n                    # It is a single frame image\n                    pass\n            number_of_pages += im_number_of_pages\n            for i in range(im_number_of_pages):\n                image_refs.append(existing_pdf.next_object_id(0))\n                page_refs.append(existing_pdf.next_object_id(0))\n                contents_refs.append(existing_pdf.next_object_id(0))\n                existing_pdf.pages.append(page_refs[-1])\n    \n        #\n        # catalog and list of pages\n        existing_pdf.write_catalog()\n    \n        page_number = 0\n        for im_sequence in ims:\n            im_pages = ImageSequence.Iterator(im_sequence) if save_all else [im_sequence]\n            for im in im_pages:\n>               procset = _write_image(im, filename, existing_pdfs, image_refs)\n\u001b[1m\u001b[31mE               NameError: name 'existing_pdfs' is not defined\u001b[0m\n\n\u001b[1m\u001b[31msrc/PIL/PdfImagePlugin.py\u001b[0m:246: NameError\n\u001b[31m\u001b[1m_______________________________ test_pdf_append ________________________________\u001b[0m\n\ntmp_path = PosixPath('/tmp/pytest-of-gcpuser/pytest-509/test_pdf_append0')\n\n    def test_pdf_append(tmp_path):\n        # make a PDF file\n>       pdf_filename = helper_save_as_pdf(tmp_path, \"RGB\", producer=\"PdfParser\")\n\n\u001b[1m\u001b[31mr2e_tests/test_1.py\u001b[0m:246: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\u001b[1m\u001b[31mr2e_tests/test_1.py\u001b[0m:20: in helper_save_as_pdf\n    im.save(outfile, **kwargs)\n\u001b[1m\u001b[31msrc/PIL/Image.py\u001b[0m:2416: in save\n    save_handler(self, fp, filename)\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\nim = <PIL.Image.Image image mode=RGB size=128x128 at 0x72FB80843CA0>\nfp = <_io.BufferedRandom name='/tmp/pytest-of-gcpuser/pytest-509/test_pdf_append0/temp_RGB.pdf'>\nfilename = '/tmp/pytest-of-gcpuser/pytest-509/test_pdf_append0/temp_RGB.pdf'\nsave_all = False\n\n    def _save(im, fp, filename, save_all=False):\n        is_appending = im.encoderinfo.get(\"append\", False)\n        if is_appending:\n            existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode=\"r+b\")\n        else:\n            existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode=\"w+b\")\n    \n        dpi = im.encoderinfo.get(\"dpi\")\n        if dpi:\n            x_resolution = dpi[0]\n            y_resolution = dpi[1]\n        else:\n            x_resolution = y_resolution = im.encoderinfo.get(\"resolution\", 72.0)\n    \n        info = {\n            \"title\": None\n            if is_appending\n            else os.path.splitext(os.path.basename(filename))[0],\n            \"author\": None,\n            \"subject\": None,\n            \"keywords\": None,\n            \"creator\": None,\n            \"producer\": None,\n            \"creationDate\": None if is_appending else time.gmtime(),\n            \"modDate\": None if is_appending else time.gmtime(),\n        }\n        for k, default in info.items():\n            v = im.encoderinfo.get(k) if k in im.encoderinfo else default\n            if v:\n                existing_pdf.info[k[0].upper() + k[1:]] = v\n    \n        #\n        # make sure image data is available\n        im.load()\n    \n        existing_pdf.start_writing()\n        existing_pdf.write_header()\n        existing_pdf.write_comment(f\"created by Pillow {__version__} PDF driver\")\n    \n        #\n        # pages\n        ims = [im]\n        if save_all:\n            append_images = im.encoderinfo.get(\"append_images\", [])\n            for append_im in append_images:\n                append_im.encoderinfo = im.encoderinfo.copy()\n                ims.append(append_im)\n        number_of_pages = 0\n        image_refs = []\n        page_refs = []\n        contents_refs = []\n        for im in ims:\n            im_number_of_pages = 1\n            if save_all:\n                try:\n                    im_number_of_pages = im.n_frames\n                except AttributeError:\n                    # Image format does not have n_frames.\n                    # It is a single frame image\n                    pass\n            number_of_pages += im_number_of_pages\n            for i in range(im_number_of_pages):\n                image_refs.append(existing_pdf.next_object_id(0))\n                page_refs.append(existing_pdf.next_object_id(0))\n                contents_refs.append(existing_pdf.next_object_id(0))\n                existing_pdf.pages.append(page_refs[-1])\n    \n        #\n        # catalog and list of pages\n        existing_pdf.write_catalog()\n    \n        page_number = 0\n        for im_sequence in ims:\n            im_pages = ImageSequence.Iterator(im_sequence) if save_all else [im_sequence]\n            for im in im_pages:\n>               procset = _write_image(im, filename, existing_pdfs, image_refs)\n\u001b[1m\u001b[31mE               NameError: name 'existing_pdfs' is not defined\u001b[0m\n\n\u001b[1m\u001b[31msrc/PIL/PdfImagePlugin.py\u001b[0m:246: NameError\n\u001b[31m\u001b[1m________________________________ test_pdf_info _________________________________\u001b[0m\n\ntmp_path = PosixPath('/tmp/pytest-of-gcpuser/pytest-509/test_pdf_info0')\n\n    def test_pdf_info(tmp_path):\n        # make a PDF file\n>       pdf_filename = helper_save_as_pdf(\n            tmp_path,\n            \"RGB\",\n            title=\"title\",\n            author=\"author\",\n            subject=\"subject\",\n            keywords=\"keywords\",\n            creator=\"creator\",\n            producer=\"producer\",\n            creationDate=time.strptime(\"2000\", \"%Y\"),\n            modDate=time.strptime(\"2001\", \"%Y\"),\n        )\n\n\u001b[1m\u001b[31mr2e_tests/test_1.py\u001b[0m:297: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\u001b[1m\u001b[31mr2e_tests/test_1.py\u001b[0m:20: in helper_save_as_pdf\n    im.save(outfile, **kwargs)\n\u001b[1m\u001b[31msrc/PIL/Image.py\u001b[0m:2416: in save\n    save_handler(self, fp, filename)\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\nim = <PIL.Image.Image image mode=RGB size=128x128 at 0x72FB808402B0>\nfp = <_io.BufferedRandom name='/tmp/pytest-of-gcpuser/pytest-509/test_pdf_info0/temp_RGB.pdf'>\nfilename = '/tmp/pytest-of-gcpuser/pytest-509/test_pdf_info0/temp_RGB.pdf'\nsave_all = False\n\n    def _save(im, fp, filename, save_all=False):\n        is_appending = im.encoderinfo.get(\"append\", False)\n        if is_appending:\n            existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode=\"r+b\")\n        else:\n            existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode=\"w+b\")\n    \n        dpi = im.encoderinfo.get(\"dpi\")\n        if dpi:\n            x_resolution = dpi[0]\n            y_resolution = dpi[1]\n        else:\n            x_resolution = y_resolution = im.encoderinfo.get(\"resolution\", 72.0)\n    \n        info = {\n            \"title\": None\n            if is_appending\n            else os.path.splitext(os.path.basename(filename))[0],\n            \"author\": None,\n            \"subject\": None,\n            \"keywords\": None,\n            \"creator\": None,\n            \"producer\": None,\n            \"creationDate\": None if is_appending else time.gmtime(),\n            \"modDate\": None if is_appending else time.gmtime(),\n        }\n        for k, default in info.items():\n            v = im.encoderinfo.get(k) if k in im.encoderinfo else default\n            if v:\n                existing_pdf.info[k[0].upper() + k[1:]] = v\n    \n        #\n        # make sure image data is available\n        im.load()\n    \n        existing_pdf.start_writing()\n        existing_pdf.write_header()\n        existing_pdf.write_comment(f\"created by Pillow {__version__} PDF driver\")\n    \n        #\n        # pages\n        ims = [im]\n        if save_all:\n            append_images = im.encoderinfo.get(\"append_images\", [])\n            for append_im in append_images:\n                append_im.encoderinfo = im.encoderinfo.copy()\n                ims.append(append_im)\n        number_of_pages = 0\n        image_refs = []\n        page_refs = []\n        contents_refs = []\n        for im in ims:\n            im_number_of_pages = 1\n            if save_all:\n                try:\n                    im_number_of_pages = im.n_frames\n                except AttributeError:\n                    # Image format does not have n_frames.\n                    # It is a single frame image\n                    pass\n            number_of_pages += im_number_of_pages\n            for i in range(im_number_of_pages):\n                image_refs.append(existing_pdf.next_object_id(0))\n                page_refs.append(existing_pdf.next_object_id(0))\n                contents_refs.append(existing_pdf.next_object_id(0))\n                existing_pdf.pages.append(page_refs[-1])\n    \n        #\n        # catalog and list of pages\n        existing_pdf.write_catalog()\n    \n        page_number = 0\n        for im_sequence in ims:\n            im_pages = ImageSequence.Iterator(im_sequence) if save_all else [im_sequence]\n            for im in im_pages:\n>               procset = _write_image(im, filename, existing_pdfs, image_refs)\n\u001b[1m\u001b[31mE               NameError: name 'existing_pdfs' is not defined\u001b[0m\n\n\u001b[1m\u001b[31msrc/PIL/PdfImagePlugin.py\u001b[0m:246: NameError\n\u001b[31m\u001b[1m__________________________ test_pdf_append_to_bytesio __________________________\u001b[0m\n\n    def test_pdf_append_to_bytesio():\n        im = hopper(\"RGB\")\n        f = io.BytesIO()\n>       im.save(f, format=\"PDF\")\n\n\u001b[1m\u001b[31mr2e_tests/test_1.py\u001b[0m:327: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\u001b[1m\u001b[31msrc/PIL/Image.py\u001b[0m:2416: in save\n    save_handler(self, fp, filename)\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\nim = <PIL.Image.Image image mode=RGB size=128x128 at 0x72FB80810790>\nfp = <_io.BytesIO object at 0x72fb8088e2c0>, filename = '', save_all = False\n\n    def _save(im, fp, filename, save_all=False):\n        is_appending = im.encoderinfo.get(\"append\", False)\n        if is_appending:\n            existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode=\"r+b\")\n        else:\n            existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode=\"w+b\")\n    \n        dpi = im.encoderinfo.get(\"dpi\")\n        if dpi:\n            x_resolution = dpi[0]\n            y_resolution = dpi[1]\n        else:\n            x_resolution = y_resolution = im.encoderinfo.get(\"resolution\", 72.0)\n    \n        info = {\n            \"title\": None\n            if is_appending\n            else os.path.splitext(os.path.basename(filename))[0],\n            \"author\": None,\n            \"subject\": None,\n            \"keywords\": None,\n            \"creator\": None,\n            \"producer\": None,\n            \"creationDate\": None if is_appending else time.gmtime(),\n            \"modDate\": None if is_appending else time.gmtime(),\n        }\n        for k, default in info.items():\n            v = im.encoderinfo.get(k) if k in im.encoderinfo else default\n            if v:\n                existing_pdf.info[k[0].upper() + k[1:]] = v\n    \n        #\n        # make sure image data is available\n        im.load()\n    \n        existing_pdf.start_writing()\n        existing_pdf.write_header()\n        existing_pdf.write_comment(f\"created by Pillow {__version__} PDF driver\")\n    \n        #\n        # pages\n        ims = [im]\n        if save_all:\n            append_images = im.encoderinfo.get(\"append_images\", [])\n            for append_im in append_images:\n                append_im.encoderinfo = im.encoderinfo.copy()\n                ims.append(append_im)\n        number_of_pages = 0\n        image_refs = []\n        page_refs = []\n        contents_refs = []\n        for im in ims:\n            im_number_of_pages = 1\n            if save_all:\n                try:\n                    im_number_of_pages = im.n_frames\n                except AttributeError:\n                    # Image format does not have n_frames.\n                    # It is a single frame image\n                    pass\n            number_of_pages += im_number_of_pages\n            for i in range(im_number_of_pages):\n                image_refs.append(existing_pdf.next_object_id(0))\n                page_refs.append(existing_pdf.next_object_id(0))\n                contents_refs.append(existing_pdf.next_object_id(0))\n                existing_pdf.pages.append(page_refs[-1])\n    \n        #\n        # catalog and list of pages\n        existing_pdf.write_catalog()\n    \n        page_number = 0\n        for im_sequence in ims:\n            im_pages = ImageSequence.Iterator(im_sequence) if save_all else [im_sequence]\n            for im in im_pages:\n>               procset = _write_image(im, filename, existing_pdfs, image_refs)\n\u001b[1m\u001b[31mE               NameError: name 'existing_pdfs' is not defined\u001b[0m\n\n\u001b[1m\u001b[31msrc/PIL/PdfImagePlugin.py\u001b[0m:246: NameError\n==================================== PASSES ====================================\n\u001b[36m\u001b[1m=========================== short test summary info ============================\u001b[0m\n\u001b[32mPASSED\u001b[0m r2e_tests/test_1.py::\u001b[1mtest_pdf_append_fails_on_nonexistent_file\u001b[0m\n\u001b[32mPASSED\u001b[0m r2e_tests/test_1.py::\u001b[1mtest_redos[\\r]\u001b[0m\n\u001b[32mPASSED\u001b[0m r2e_tests/test_1.py::\u001b[1mtest_redos[\\n]\u001b[0m\n\u001b[33mSKIPPED\u001b[0m [2] r2e_tests/test_1.py:45: jpg_2000 not available\n\u001b[31mFAILED\u001b[0m r2e_tests/test_1.py::\u001b[1mtest_save[L]\u001b[0m - NameError: name 'existing_pdfs' is not defined\n\u001b[31mFAILED\u001b[0m r2e_tests/test_1.py::\u001b[1mtest_save[P]\u001b[0m - NameError: name 'existing_pdfs' is not defined\n\u001b[31mFAILED\u001b[0m r2e_tests/test_1.py::\u001b[1mtest_save[RGB]\u001b[0m - NameError: name 'existing_pdfs' is not defined\n\u001b[31mFAILED\u001b[0m r2e_tests/test_1.py::\u001b[1mtest_save[CMYK]\u001b[0m - NameError: name 'existing_pdfs' is not defined\n\u001b[31mFAILED\u001b[0m r2e_tests/test_1.py::\u001b[1mtest_p_alpha\u001b[0m - NameError: name 'existing_pdfs' is not defined\n\u001b[31mFAILED\u001b[0m r2e_tests/test_1.py::\u001b[1mtest_monochrome\u001b[0m - NameError: name 'existing_pdfs' is not defined\n\u001b[31mFAILED\u001b[0m r2e_tests/test_1.py::\u001b[1mtest_unsupported_mode\u001b[0m - NameError: name 'existing_pdfs' is not defined\n\u001b[31mFAILED\u001b[0m r2e_tests/test_1.py::\u001b[1mtest_resolution\u001b[0m - NameError: name 'existing_pdfs' is not defined\n\u001b[31mFAILED\u001b[0m r2e_tests/test_1.py::\u001b[1mtest_dpi[params0]\u001b[0m - NameError: name 'existing_pdfs' is not defined\n\u001b[31mFAILED\u001b[0m r2e_tests/test_1.py::\u001b[1mtest_dpi[params1]\u001b[0m - NameError: name 'existing_pdfs' is not defined\n\u001b[31mFAILED\u001b[0m r2e_tests/test_1.py::\u001b[1mtest_save_all\u001b[0m - NameError: name 'existing_pdfs' is not defined\n\u001b[31mFAILED\u001b[0m r2e_tests/test_1.py::\u001b[1mtest_multiframe_normal_save\u001b[0m - NameError: name 'existing_pdfs' is not defined\n\u001b[31mFAILED\u001b[0m r2e_tests/test_1.py::\u001b[1mtest_pdf_open\u001b[0m - NameError: name 'existing_pdfs' is not defined\n\u001b[31mFAILED\u001b[0m r2e_tests/test_1.py::\u001b[1mtest_pdf_append\u001b[0m - NameError: name 'existing_pdfs' is not defined\n\u001b[31mFAILED\u001b[0m r2e_tests/test_1.py::\u001b[1mtest_pdf_info\u001b[0m - NameError: name 'existing_pdfs' is not defined\n\u001b[31mFAILED\u001b[0m r2e_tests/test_1.py::\u001b[1mtest_pdf_append_to_bytesio\u001b[0m - NameError: name 'existing_pdfs' is not defined\n\u001b[31m=================== \u001b[31m\u001b[1m16 failed\u001b[0m, \u001b[32m3 passed\u001b[0m, \u001b[33m2 skipped\u001b[0m\u001b[31m in 1.44s\u001b[0m\u001b[31m ====================\u001b[0m\n",
    "old_commit_res_stderr": ""
}
Tests/test_file_pdf.py src/PIL/PdfImagePlugin.py
We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[ISSUE]
**Title:** NameError When Saving 'P' Mode Images with Transparency to PDF

**Description:**
When attempting to save an image in 'P' (paletted) mode with transparency to a PDF file, a `NameError` is raised due to an undefined variable.

**Example Code:**
```python
from PIL import Image

def save_p_image_with_transparency():
    # Open a 'P' mode image with transparency
    im = Image.open("Tests/images/pil123p.png")
    im.save("output.pdf")
```

**Expected Behavior:**
The image should be successfully saved as a PDF with proper handling of transparency using the `SMask` attribute.

**Actual Behavior:**
A `NameError` is raised indicating that `'existing_pdfs'` is not defined.

```
NameError: name 'existing_pdfs' is not defined
```

This error prevents the image from being saved correctly and indicates a bug in handling transparency for 'P' mode images in PDF exports.
[/ISSUE]
--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.

--- BEGIN FILE ---
```
### src/PIL/PdfImagePlugin.py
#
# The Python Imaging Library.
# $Id$
#
# PDF (Acrobat) file handling
#
# History:
# 1996-07-16 fl   Created
# 1997-01-18 fl   Fixed header
# 2004-02-21 fl   Fixes for 1/L/CMYK images, etc.
# 2004-02-24 fl   Fixes for 1 and P images.
#
# Copyright (c) 1997-2004 by Secret Labs AB.  All rights reserved.
# Copyright (c) 1996-1997 by Fredrik Lundh.
#
# See the README file for information on usage and redistribution.
#

##
# Image plugin for PDF images (output only).
##

import io
import math
import os
import time

from . import Image, ImageFile, ImageSequence, PdfParser, __version__, features

#
# --------------------------------------------------------------------

# object ids:
#  1. catalogue
#  2. pages
#  3. image
#  4. page
#  5. page contents


def _save_all(im, fp, filename):
    _save(im, fp, filename, save_all=True)


##
# (Internal) Image save plugin for the PDF format.


def _write_image(im, filename, existing_pdf, image_refs):
    # FIXME: Should replace ASCIIHexDecode with RunLengthDecode
    # (packbits) or LZWDecode (tiff/lzw compression).  Note that
    # PDF 1.2 also supports Flatedecode (zip compression).

    params = None
    decode = None

    #
    # Get image characteristics

    width, height = im.size

    dict_obj = {"BitsPerComponent": 8}
    if im.mode == "1":
        if features.check("libtiff"):
            filter = "CCITTFaxDecode"
            dict_obj["BitsPerComponent"] = 1
            params = PdfParser.PdfArray(
                [
                    PdfParser.PdfDict(
                        {
                            "K": -1,
                            "BlackIs1": True,
                            "Columns": width,
                            "Rows": height,
                        }
                    )
                ]
            )
        else:
            filter = "DCTDecode"
        dict_obj["ColorSpace"] = PdfParser.PdfName("DeviceGray")
        procset = "ImageB"  # grayscale
    elif im.mode == "L":
        filter = "DCTDecode"
        # params = f"<< /Predictor 15 /Columns {width-2} >>"
        dict_obj["ColorSpace"] = PdfParser.PdfName("DeviceGray")
        procset = "ImageB"  # grayscale
    elif im.mode == "LA":
        filter = "JPXDecode"
        # params = f"<< /Predictor 15 /Columns {width-2} >>"
        procset = "ImageB"  # grayscale
        dict_obj["SMaskInData"] = 1
    elif im.mode == "P":
        filter = "ASCIIHexDecode"
        palette = im.getpalette()
        dict_obj["ColorSpace"] = [
            PdfParser.PdfName("Indexed"),
            PdfParser.PdfName("DeviceRGB"),
            255,
            PdfParser.PdfBinary(palette),
        ]
        procset = "ImageI"  # indexed color
    elif im.mode == "RGB":
        filter = "DCTDecode"
        dict_obj["ColorSpace"] = PdfParser.PdfName("DeviceRGB")
        procset = "ImageC"  # color images
    elif im.mode == "RGBA":
        filter = "JPXDecode"
        procset = "ImageC"  # color images
        dict_obj["SMaskInData"] = 1
    elif im.mode == "CMYK":
        filter = "DCTDecode"
        dict_obj["ColorSpace"] = PdfParser.PdfName("DeviceCMYK")
        procset = "ImageC"  # color images
        decode = [1, 0, 1, 0, 1, 0, 1, 0]
    else:
        msg = f"cannot save mode {im.mode}"
        raise ValueError(msg)

    #
    # image

    op = io.BytesIO()

    if filter == "ASCIIHexDecode":
        ImageFile._save(im, op, [("hex", (0, 0) + im.size, 0, im.mode)])
    elif filter == "CCITTFaxDecode":
        im.save(
            op,
            "TIFF",
            compression="group4",
            # use a single strip
            strip_size=math.ceil(im.width / 8) * im.height,
        )
    elif filter == "DCTDecode":
        Image.SAVE["JPEG"](im, op, filename)
    elif filter == "JPXDecode":
        del dict_obj["BitsPerComponent"]
        Image.SAVE["JPEG2000"](im, op, filename)
    elif filter == "FlateDecode":
        ImageFile._save(im, op, [("zip", (0, 0) + im.size, 0, im.mode)])
    elif filter == "RunLengthDecode":
        ImageFile._save(im, op, [("packbits", (0, 0) + im.size, 0, im.mode)])
    else:
        msg = f"unsupported PDF filter ({filter})"
        raise ValueError(msg)

    stream = op.getvalue()
    if filter == "CCITTFaxDecode":
        stream = stream[8:]
        filter = PdfParser.PdfArray([PdfParser.PdfName(filter)])
    else:
        filter = PdfParser.PdfName(filter)

    existing_pdf.write_obj(
        image_refs[page_number],
        stream=stream,
        Type=PdfParser.PdfName("XObject"),
        Subtype=PdfParser.PdfName("Image"),
        Width=width,  # * 72.0 / x_resolution,
        Height=height,  # * 72.0 / y_resolution,
        Filter=filter,
        Decode=decode,
        DecodeParms=params,
        **dict_obj,
    )

    return procset


def _save(im, fp, filename, save_all=False):
    is_appending = im.encoderinfo.get("append", False)
    if is_appending:
        existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode="r+b")
    else:
        existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode="w+b")

    dpi = im.encoderinfo.get("dpi")
    if dpi:
        x_resolution = dpi[0]
        y_resolution = dpi[1]
    else:
        x_resolution = y_resolution = im.encoderinfo.get("resolution", 72.0)

    info = {
        "title": None
        if is_appending
        else os.path.splitext(os.path.basename(filename))[0],
        "author": None,
        "subject": None,
        "keywords": None,
        "creator": None,
        "producer": None,
        "creationDate": None if is_appending else time.gmtime(),
        "modDate": None if is_appending else time.gmtime(),
    }
    for k, default in info.items():
        v = im.encoderinfo.get(k) if k in im.encoderinfo else default
        if v:
            existing_pdf.info[k[0].upper() + k[1:]] = v

    #
    # make sure image data is available
    im.load()

    existing_pdf.start_writing()
    existing_pdf.write_header()
    existing_pdf.write_comment(f"created by Pillow {__version__} PDF driver")

    #
    # pages
    ims = [im]
    if save_all:
        append_images = im.encoderinfo.get("append_images", [])
        for append_im in append_images:
            append_im.encoderinfo = im.encoderinfo.copy()
            ims.append(append_im)
    number_of_pages = 0
    image_refs = []
    page_refs = []
    contents_refs = []
    for im in ims:
        im_number_of_pages = 1
        if save_all:
            try:
                im_number_of_pages = im.n_frames
            except AttributeError:
                # Image format does not have n_frames.
                # It is a single frame image
                pass
        number_of_pages += im_number_of_pages
        for i in range(im_number_of_pages):
            image_refs.append(existing_pdf.next_object_id(0))
            page_refs.append(existing_pdf.next_object_id(0))
            contents_refs.append(existing_pdf.next_object_id(0))
            existing_pdf.pages.append(page_refs[-1])

    #
    # catalog and list of pages
    existing_pdf.write_catalog()

    page_number = 0
    for im_sequence in ims:
        im_pages = ImageSequence.Iterator(im_sequence) if save_all else [im_sequence]
        for im in im_pages:
            procset = _write_image(im, filename, existing_pdfs, image_refs)

            #
            # page

            existing_pdf.write_page(
                page_refs[page_number],
                Resources=PdfParser.PdfDict(
                    ProcSet=[PdfParser.PdfName("PDF"), PdfParser.PdfName(procset)],
                    XObject=PdfParser.PdfDict(image=image_refs[page_number]),
                ),
                MediaBox=[
                    0,
                    0,
                    im.width * 72.0 / x_resolution,
                    im.height * 72.0 / y_resolution,
                ],
                Contents=contents_refs[page_number],
            )

            #
            # page contents

            page_contents = b"q %f 0 0 %f 0 0 cm /image Do Q\n" % (
                im.width * 72.0 / x_resolution,
                im.height * 72.0 / y_resolution,
            )

            existing_pdf.write_obj(contents_refs[page_number], stream=page_contents)

            page_number += 1

    #
    # trailer
    existing_pdf.write_xref_and_trailer()
    if hasattr(fp, "flush"):
        fp.flush()
    existing_pdf.close()


#
# --------------------------------------------------------------------


Image.register_save("PDF", _save)
Image.register_save_all("PDF", _save_all)

Image.register_extension("PDF", ".pdf")

Image.register_mime("PDF", "application/pdf")

```
--- END FILE ---

Please first localize the bug based on the issue statement, and then generate *SEARCH/REPLACE* edits to fix the issue.

Every *SEARCH/REPLACE* edit must use this format:
1. The file path
2. The start of search block: <<<<<<< SEARCH
3. A contiguous chunk of lines to search for in the existing source code
4. The dividing line: =======
5. The lines to replace into the source code
6. The end of the replace block: >>>>>>> REPLACE

Here is an example:

```python
### mathweb/flask/app.py
<<<<<<< SEARCH
from flask import Flask
=======
import math
from flask import Flask
>>>>>>> REPLACE
```
</solution>

Please note that the *SEARCH/REPLACE* edit REQUIRES PROPER INDENTATION. If you would like to add the line '        print(x)', you must fully write that out, with all those spaces before the code!
Wrap each *SEARCH/REPLACE* edit in a code block as shown in the example above. If you have multiple *SEARCH/REPLACE* edits, use a separate code block for each one.
[ISSUE]
**Title:** NameError When Saving 'P' Mode Images with Transparency to PDF

**Description:**
When attempting to save an image in 'P' (paletted) mode with transparency to a PDF file, a `NameError` is raised due to an undefined variable.

**Example Code:**
```python
from PIL import Image

def save_p_image_with_transparency():
    # Open a 'P' mode image with transparency
    im = Image.open("Tests/images/pil123p.png")
    im.save("output.pdf")
```

**Expected Behavior:**
The image should be successfully saved as a PDF with proper handling of transparency using the `SMask` attribute.

**Actual Behavior:**
A `NameError` is raised indicating that `'existing_pdfs'` is not defined.

```
NameError: name 'existing_pdfs' is not defined
```

This error prevents the image from being saved correctly and indicates a bug in handling transparency for 'P' mode images in PDF exports.
[/ISSUE]
{
    "\u001b[1mtest_save[L]\u001b[0m": "PASSED",
    "\u001b[1mtest_save[P]\u001b[0m": "PASSED",
    "\u001b[1mtest_save[RGB]\u001b[0m": "PASSED",
    "\u001b[1mtest_save[CMYK]\u001b[0m": "PASSED",
    "\u001b[1mtest_p_alpha\u001b[0m": "PASSED",
    "\u001b[1mtest_monochrome\u001b[0m": "PASSED",
    "\u001b[1mtest_unsupported_mode\u001b[0m": "PASSED",
    "\u001b[1mtest_resolution\u001b[0m": "PASSED",
    "\u001b[1mtest_dpi[params0]\u001b[0m": "PASSED",
    "\u001b[1mtest_dpi[params1]\u001b[0m": "PASSED",
    "\u001b[1mtest_save_all\u001b[0m": "PASSED",
    "\u001b[1mtest_multiframe_normal_save\u001b[0m": "PASSED",
    "\u001b[1mtest_pdf_open\u001b[0m": "PASSED",
    "\u001b[1mtest_pdf_append_fails_on_nonexistent_file\u001b[0m": "PASSED",
    "\u001b[1mtest_pdf_append\u001b[0m": "PASSED",
    "\u001b[1mtest_pdf_info\u001b[0m": "PASSED",
    "\u001b[1mtest_pdf_append_to_bytesio\u001b[0m": "PASSED",
    "\u001b[1mtest_redos[\\r]\u001b[0m": "PASSED",
    "\u001b[1mtest_redos[\\n]\u001b[0m": "PASSED"
}
diff --git a/src/PIL/PdfImagePlugin.py b/src/PIL/PdfImagePlugin.py
index be39f4d16..e3af1b452 100644
--- a/src/PIL/PdfImagePlugin.py
+++ b/src/PIL/PdfImagePlugin.py
@@ -100,6 +100,13 @@ def _write_image(im, filename, existing_pdf, image_refs):
             PdfParser.PdfBinary(palette),
         ]
         procset = "ImageI"  # indexed color
+
+        if "transparency" in im.info:
+            smask = im.convert("LA").getchannel("A")
+            smask.encoderinfo = {}
+
+            image_ref = _write_image(smask, filename, existing_pdf, image_refs)[0]
+            dict_obj["SMask"] = image_ref
     elif im.mode == "RGB":
         filter = "DCTDecode"
         dict_obj["ColorSpace"] = PdfParser.PdfName("DeviceRGB")
@@ -130,7 +137,7 @@ def _write_image(im, filename, existing_pdf, image_refs):
             "TIFF",
             compression="group4",
             # use a single strip
-            strip_size=math.ceil(im.width / 8) * im.height,
+            strip_size=math.ceil(width / 8) * height,
         )
     elif filter == "DCTDecode":
         Image.SAVE["JPEG"](im, op, filename)
@@ -152,8 +159,9 @@ def _write_image(im, filename, existing_pdf, image_refs):
     else:
         filter = PdfParser.PdfName(filter)
 
+    image_ref = image_refs.pop(0)
     existing_pdf.write_obj(
-        image_refs[page_number],
+        image_ref,
         stream=stream,
         Type=PdfParser.PdfName("XObject"),
         Subtype=PdfParser.PdfName("Image"),
@@ -165,7 +173,7 @@ def _write_image(im, filename, existing_pdf, image_refs):
         **dict_obj,
     )
 
-    return procset
+    return image_ref, procset
 
 
 def _save(im, fp, filename, save_all=False):
@@ -231,6 +239,9 @@ def _save(im, fp, filename, save_all=False):
         number_of_pages += im_number_of_pages
         for i in range(im_number_of_pages):
             image_refs.append(existing_pdf.next_object_id(0))
+            if im.mode == "P" and "transparency" in im.info:
+                image_refs.append(existing_pdf.next_object_id(0))
+
             page_refs.append(existing_pdf.next_object_id(0))
             contents_refs.append(existing_pdf.next_object_id(0))
             existing_pdf.pages.append(page_refs[-1])
@@ -243,7 +254,7 @@ def _save(im, fp, filename, save_all=False):
     for im_sequence in ims:
         im_pages = ImageSequence.Iterator(im_sequence) if save_all else [im_sequence]
         for im in im_pages:
-            procset = _write_image(im, filename, existing_pdfs, image_refs)
+            image_ref, procset = _write_image(im, filename, existing_pdf, image_refs)
 
             #
             # page
@@ -252,7 +263,7 @@ def _save(im, fp, filename, save_all=False):
                 page_refs[page_number],
                 Resources=PdfParser.PdfDict(
                     ProcSet=[PdfParser.PdfName("PDF"), PdfParser.PdfName(procset)],
-                    XObject=PdfParser.PdfDict(image=image_refs[page_number]),
+                    XObject=PdfParser.PdfDict(image=image_ref),
                 ),
                 MediaBox=[
                     0,
 

{"src/PIL/PdfImagePlugin.py": "#\n# The Python Imaging Library.\n# $Id$\n#\n# PDF (Acrobat) file handling\n#\n# History:\n# 1996-07-16 fl   Created\n# 1997-01-18 fl   Fixed header\n# 2004-02-21 fl   Fixes for 1/L/CMYK images, etc.\n# 2004-02-24 fl   Fixes for 1 and P images.\n#\n# Copyright (c) 1997-2004 by Secret Labs AB.  All rights reserved.\n# Copyright (c) 1996-1997 by Fredrik Lundh.\n#\n# See the README file for information on usage and redistribution.\n#\n\n##\n# Image plugin for PDF images (output only).\n##\n\nimport io\nimport math\nimport os\nimport time\n\nfrom . import Image, ImageFile, ImageSequence, PdfParser, __version__, features\n\n#\n# --------------------------------------------------------------------\n\n# object ids:\n#  1. catalogue\n#  2. pages\n#  3. image\n#  4. page\n#  5. page contents\n\n\ndef _save_all(im, fp, filename):\n    _save(im, fp, filename, save_all=True)\n\n\n##\n# (Internal) Image save plugin for the PDF format.\n\n\ndef _write_image(im, filename, existing_pdf, image_refs):\n    # FIXME: Should replace ASCIIHexDecode with RunLengthDecode\n    # (packbits) or LZWDecode (tiff/lzw compression).  Note that\n    # PDF 1.2 also supports Flatedecode (zip compression).\n\n    params = None\n    decode = None\n\n    #\n    # Get image characteristics\n\n    width, height = im.size\n\n    dict_obj = {\"BitsPerComponent\": 8}\n    if im.mode == \"1\":\n        if features.check(\"libtiff\"):\n            filter = \"CCITTFaxDecode\"\n            dict_obj[\"BitsPerComponent\"] = 1\n            params = PdfParser.PdfArray(\n                [\n                    PdfParser.PdfDict(\n                        {\n                            \"K\": -1,\n                            \"BlackIs1\": True,\n                            \"Columns\": width,\n                            \"Rows\": height,\n                        }\n                    )\n                ]\n            )\n        else:\n            filter = \"DCTDecode\"\n        dict_obj[\"ColorSpace\"] = PdfParser.PdfName(\"DeviceGray\")\n        procset = \"ImageB\"  # grayscale\n    elif im.mode == \"L\":\n        filter = \"DCTDecode\"\n        # params = f\"<< /Predictor 15 /Columns {width-2} >>\"\n        dict_obj[\"ColorSpace\"] = PdfParser.PdfName(\"DeviceGray\")\n        procset = \"ImageB\"  # grayscale\n    elif im.mode == \"LA\":\n        filter = \"JPXDecode\"\n        # params = f\"<< /Predictor 15 /Columns {width-2} >>\"\n        procset = \"ImageB\"  # grayscale\n        dict_obj[\"SMaskInData\"] = 1\n    elif im.mode == \"P\":\n        filter = \"ASCIIHexDecode\"\n        palette = im.getpalette()\n        dict_obj[\"ColorSpace\"] = [\n            PdfParser.PdfName(\"Indexed\"),\n            PdfParser.PdfName(\"DeviceRGB\"),\n            255,\n            PdfParser.PdfBinary(palette),\n        ]\n        procset = \"ImageI\"  # indexed color\n    elif im.mode == \"RGB\":\n        filter = \"DCTDecode\"\n        dict_obj[\"ColorSpace\"] = PdfParser.PdfName(\"DeviceRGB\")\n        procset = \"ImageC\"  # color images\n    elif im.mode == \"RGBA\":\n        filter = \"JPXDecode\"\n        procset = \"ImageC\"  # color images\n        dict_obj[\"SMaskInData\"] = 1\n    elif im.mode == \"CMYK\":\n        filter = \"DCTDecode\"\n        dict_obj[\"ColorSpace\"] = PdfParser.PdfName(\"DeviceCMYK\")\n        procset = \"ImageC\"  # color images\n        decode = [1, 0, 1, 0, 1, 0, 1, 0]\n    else:\n        msg = f\"cannot save mode {im.mode}\"\n        raise ValueError(msg)\n\n    #\n    # image\n\n    op = io.BytesIO()\n\n    if filter == \"ASCIIHexDecode\":\n        ImageFile._save(im, op, [(\"hex\", (0, 0) + im.size, 0, im.mode)])\n    elif filter == \"CCITTFaxDecode\":\n        im.save(\n            op,\n            \"TIFF\",\n            compression=\"group4\",\n            # use a single strip\n            strip_size=math.ceil(im.width / 8) * im.height,\n        )\n    elif filter == \"DCTDecode\":\n        Image.SAVE[\"JPEG\"](im, op, filename)\n    elif filter == \"JPXDecode\":\n        del dict_obj[\"BitsPerComponent\"]\n        Image.SAVE[\"JPEG2000\"](im, op, filename)\n    elif filter == \"FlateDecode\":\n        ImageFile._save(im, op, [(\"zip\", (0, 0) + im.size, 0, im.mode)])\n    elif filter == \"RunLengthDecode\":\n        ImageFile._save(im, op, [(\"packbits\", (0, 0) + im.size, 0, im.mode)])\n    else:\n        msg = f\"unsupported PDF filter ({filter})\"\n        raise ValueError(msg)\n\n    stream = op.getvalue()\n    if filter == \"CCITTFaxDecode\":\n        stream = stream[8:]\n        filter = PdfParser.PdfArray([PdfParser.PdfName(filter)])\n    else:\n        filter = PdfParser.PdfName(filter)\n\n    existing_pdf.write_obj(\n        image_refs[page_number],\n        stream=stream,\n        Type=PdfParser.PdfName(\"XObject\"),\n        Subtype=PdfParser.PdfName(\"Image\"),\n        Width=width,  # * 72.0 / x_resolution,\n        Height=height,  # * 72.0 / y_resolution,\n        Filter=filter,\n        Decode=decode,\n        DecodeParms=params,\n        **dict_obj,\n    )\n\n    return procset\n\n\ndef _save(im, fp, filename, save_all=False):\n    is_appending = im.encoderinfo.get(\"append\", False)\n    if is_appending:\n        existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode=\"r+b\")\n    else:\n        existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode=\"w+b\")\n\n    dpi = im.encoderinfo.get(\"dpi\")\n    if dpi:\n        x_resolution = dpi[0]\n        y_resolution = dpi[1]\n    else:\n        x_resolution = y_resolution = im.encoderinfo.get(\"resolution\", 72.0)\n\n    info = {\n        \"title\": None\n        if is_appending\n        else os.path.splitext(os.path.basename(filename))[0],\n        \"author\": None,\n        \"subject\": None,\n        \"keywords\": None,\n        \"creator\": None,\n        \"producer\": None,\n        \"creationDate\": None if is_appending else time.gmtime(),\n        \"modDate\": None if is_appending else time.gmtime(),\n    }\n    for k, default in info.items():\n        v = im.encoderinfo.get(k) if k in im.encoderinfo else default\n        if v:\n            existing_pdf.info[k[0].upper() + k[1:]] = v\n\n    #\n    # make sure image data is available\n    im.load()\n\n    existing_pdf.start_writing()\n    existing_pdf.write_header()\n    existing_pdf.write_comment(f\"created by Pillow {__version__} PDF driver\")\n\n    #\n    # pages\n    ims = [im]\n    if save_all:\n        append_images = im.encoderinfo.get(\"append_images\", [])\n        for append_im in append_images:\n            append_im.encoderinfo = im.encoderinfo.copy()\n            ims.append(append_im)\n    number_of_pages = 0\n    image_refs = []\n    page_refs = []\n    contents_refs = []\n    for im in ims:\n        im_number_of_pages = 1\n        if save_all:\n            try:\n                im_number_of_pages = im.n_frames\n            except AttributeError:\n                # Image format does not have n_frames.\n                # It is a single frame image\n                pass\n        number_of_pages += im_number_of_pages\n        for i in range(im_number_of_pages):\n            image_refs.append(existing_pdf.next_object_id(0))\n            page_refs.append(existing_pdf.next_object_id(0))\n            contents_refs.append(existing_pdf.next_object_id(0))\n            existing_pdf.pages.append(page_refs[-1])\n\n    #\n    # catalog and list of pages\n    existing_pdf.write_catalog()\n\n    page_number = 0\n    for im_sequence in ims:\n        im_pages = ImageSequence.Iterator(im_sequence) if save_all else [im_sequence]\n        for im in im_pages:\n            procset = _write_image(im, filename, existing_pdfs, image_refs)\n\n            #\n            # page\n\n            existing_pdf.write_page(\n                page_refs[page_number],\n                Resources=PdfParser.PdfDict(\n                    ProcSet=[PdfParser.PdfName(\"PDF\"), PdfParser.PdfName(procset)],\n                    XObject=PdfParser.PdfDict(image=image_refs[page_number]),\n                ),\n                MediaBox=[\n                    0,\n                    0,\n                    im.width * 72.0 / x_resolution,\n                    im.height * 72.0 / y_resolution,\n                ],\n                Contents=contents_refs[page_number],\n            )\n\n            #\n            # page contents\n\n            page_contents = b\"q %f 0 0 %f 0 0 cm /image Do Q\\n\" % (\n                im.width * 72.0 / x_resolution,\n                im.height * 72.0 / y_resolution,\n            )\n\n            existing_pdf.write_obj(contents_refs[page_number], stream=page_contents)\n\n            page_number += 1\n\n    #\n    # trailer\n    existing_pdf.write_xref_and_trailer()\n    if hasattr(fp, \"flush\"):\n        fp.flush()\n    existing_pdf.close()\n\n\n#\n# --------------------------------------------------------------------\n\n\nImage.register_save(\"PDF\", _save)\nImage.register_save_all(\"PDF\", _save_all)\n\nImage.register_extension(\"PDF\", \".pdf\")\n\nImage.register_mime(\"PDF\", \"application/pdf\")\n"}
A user will ask you to solve a task. You should first draft your thinking process (inner monologue). Then, generate the solution.

Your response format must follow the template below:
<think>
Your thoughts or/and draft, like working through an exercise on scratch paper. Be as casual and as long as you want until you are confident to generate a correct solution.
</think>
<solution>
Final solution presented to the user.
</solution>
system
We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[ISSUE]
**Title:** NameError When Saving 'P' Mode Images with Transparency to PDF

**Description:**
When attempting to save an image in 'P' (paletted) mode with transparency to a PDF file, a `NameError` is raised due to an undefined variable.

**Example Code:**
```python
from PIL import Image

def save_p_image_with_transparency():
    # Open a 'P' mode image with transparency
    im = Image.open("Tests/images/pil123p.png")
    im.save("output.pdf")
```

**Expected Behavior:**
The image should be successfully saved as a PDF with proper handling of transparency using the `SMask` attribute.

**Actual Behavior:**
A `NameError` is raised indicating that `'existing_pdfs'` is not defined.

```
NameError: name 'existing_pdfs' is not defined
```

This error prevents the image from being saved correctly and indicates a bug in handling transparency for 'P' mode images in PDF exports.
[/ISSUE]
--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.

--- BEGIN FILE ---
```
### src/PIL/PdfImagePlugin.py
#
# The Python Imaging Library.
# $Id$
#
# PDF (Acrobat) file handling
#
# History:
# 1996-07-16 fl   Created
# 1997-01-18 fl   Fixed header
# 2004-02-21 fl   Fixes for 1/L/CMYK images, etc.
# 2004-02-24 fl   Fixes for 1 and P images.
#
# Copyright (c) 1997-2004 by Secret Labs AB.  All rights reserved.
# Copyright (c) 1996-1997 by Fredrik Lundh.
#
# See the README file for information on usage and redistribution.
#

##
# Image plugin for PDF images (output only).
##

import io
import math
import os
import time

from . import Image, ImageFile, ImageSequence, PdfParser, __version__, features

#
# --------------------------------------------------------------------

# object ids:
#  1. catalogue
#  2. pages
#  3. image
#  4. page
#  5. page contents


def _save_all(im, fp, filename):
    _save(im, fp, filename, save_all=True)


##
# (Internal) Image save plugin for the PDF format.


def _write_image(im, filename, existing_pdf, image_refs):
    # FIXME: Should replace ASCIIHexDecode with RunLengthDecode
    # (packbits) or LZWDecode (tiff/lzw compression).  Note that
    # PDF 1.2 also supports Flatedecode (zip compression).

    params = None
    decode = None

    #
    # Get image characteristics

    width, height = im.size

    dict_obj = {"BitsPerComponent": 8}
    if im.mode == "1":
        if features.check("libtiff"):
            filter = "CCITTFaxDecode"
            dict_obj["BitsPerComponent"] = 1
            params = PdfParser.PdfArray(
                [
                    PdfParser.PdfDict(
                        {
                            "K": -1,
                            "BlackIs1": True,
                            "Columns": width,
                            "Rows": height,
                        }
                    )
                ]
            )
        else:
            filter = "DCTDecode"
        dict_obj["ColorSpace"] = PdfParser.PdfName("DeviceGray")
        procset = "ImageB"  # grayscale
    elif im.mode == "L":
        filter = "DCTDecode"
        # params = f"<< /Predictor 15 /Columns {width-2} >>"
        dict_obj["ColorSpace"] = PdfParser.PdfName("DeviceGray")
        procset = "ImageB"  # grayscale
    elif im.mode == "LA":
        filter = "JPXDecode"
        # params = f"<< /Predictor 15 /Columns {width-2} >>"
        procset = "ImageB"  # grayscale
        dict_obj["SMaskInData"] = 1
    elif im.mode == "P":
        filter = "ASCIIHexDecode"
        palette = im.getpalette()
        dict_obj["ColorSpace"] = [
            PdfParser.PdfName("Indexed"),
            PdfParser.PdfName("DeviceRGB"),
            255,
            PdfParser.PdfBinary(palette),
        ]
        procset = "ImageI"  # indexed color
    elif im.mode == "RGB":
        filter = "DCTDecode"
        dict_obj["ColorSpace"] = PdfParser.PdfName("DeviceRGB")
        procset = "ImageC"  # color images
    elif im.mode == "RGBA":
        filter = "JPXDecode"
        procset = "ImageC"  # color images
        dict_obj["SMaskInData"] = 1
    elif im.mode == "CMYK":
        filter = "DCTDecode"
        dict_obj["ColorSpace"] = PdfParser.PdfName("DeviceCMYK")
        procset = "ImageC"  # color images
        decode = [1, 0, 1, 0, 1, 0, 1, 0]
    else:
        msg = f"cannot save mode {im.mode}"
        raise ValueError(msg)

    #
    # image

    op = io.BytesIO()

    if filter == "ASCIIHexDecode":
        ImageFile._save(im, op, [("hex", (0, 0) + im.size, 0, im.mode)])
    elif filter == "CCITTFaxDecode":
        im.save(
            op,
            "TIFF",
            compression="group4",
            # use a single strip
            strip_size=math.ceil(im.width / 8) * im.height,
        )
    elif filter == "DCTDecode":
        Image.SAVE["JPEG"](im, op, filename)
    elif filter == "JPXDecode":
        del dict_obj["BitsPerComponent"]
        Image.SAVE["JPEG2000"](im, op, filename)
    elif filter == "FlateDecode":
        ImageFile._save(im, op, [("zip", (0, 0) + im.size, 0, im.mode)])
    elif filter == "RunLengthDecode":
        ImageFile._save(im, op, [("packbits", (0, 0) + im.size, 0, im.mode)])
    else:
        msg = f"unsupported PDF filter ({filter})"
        raise ValueError(msg)

    stream = op.getvalue()
    if filter == "CCITTFaxDecode":
        stream = stream[8:]
        filter = PdfParser.PdfArray([PdfParser.PdfName(filter)])
    else:
        filter = PdfParser.PdfName(filter)

    existing_pdf.write_obj(
        image_refs[page_number],
        stream=stream,
        Type=PdfParser.PdfName("XObject"),
        Subtype=PdfParser.PdfName("Image"),
        Width=width,  # * 72.0 / x_resolution,
        Height=height,  # * 72.0 / y_resolution,
        Filter=filter,
        Decode=decode,
        DecodeParms=params,
        **dict_obj,
    )

    return procset


def _save(im, fp, filename, save_all=False):
    is_appending = im.encoderinfo.get("append", False)
    if is_appending:
        existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode="r+b")
    else:
        existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode="w+b")

    dpi = im.encoderinfo.get("dpi")
    if dpi:
        x_resolution = dpi[0]
        y_resolution = dpi[1]
    else:
        x_resolution = y_resolution = im.encoderinfo.get("resolution", 72.0)

    info = {
        "title": None
        if is_appending
        else os.path.splitext(os.path.basename(filename))[0],
        "author": None,
        "subject": None,
        "keywords": None,
        "creator": None,
        "producer": None,
        "creationDate": None if is_appending else time.gmtime(),
        "modDate": None if is_appending else time.gmtime(),
    }
    for k, default in info.items():
        v = im.encoderinfo.get(k) if k in im.encoderinfo else default
        if v:
            existing_pdf.info[k[0].upper() + k[1:]] = v

    #
    # make sure image data is available
    im.load()

    existing_pdf.start_writing()
    existing_pdf.write_header()
    existing_pdf.write_comment(f"created by Pillow {__version__} PDF driver")

    #
    # pages
    ims = [im]
    if save_all:
        append_images = im.encoderinfo.get("append_images", [])
        for append_im in append_images:
            append_im.encoderinfo = im.encoderinfo.copy()
            ims.append(append_im)
    number_of_pages = 0
    image_refs = []
    page_refs = []
    contents_refs = []
    for im in ims:
        im_number_of_pages = 1
        if save_all:
            try:
                im_number_of_pages = im.n_frames
            except AttributeError:
                # Image format does not have n_frames.
                # It is a single frame image
                pass
        number_of_pages += im_number_of_pages
        for i in range(im_number_of_pages):
            image_refs.append(existing_pdf.next_object_id(0))
            page_refs.append(existing_pdf.next_object_id(0))
            contents_refs.append(existing_pdf.next_object_id(0))
            existing_pdf.pages.append(page_refs[-1])

    #
    # catalog and list of pages
    existing_pdf.write_catalog()

    page_number = 0
    for im_sequence in ims:
        im_pages = ImageSequence.Iterator(im_sequence) if save_all else [im_sequence]
        for im in im_pages:
            procset = _write_image(im, filename, existing_pdfs, image_refs)

            #
            # page

            existing_pdf.write_page(
                page_refs[page_number],
                Resources=PdfParser.PdfDict(
                    ProcSet=[PdfParser.PdfName("PDF"), PdfParser.PdfName(procset)],
                    XObject=PdfParser.PdfDict(image=image_refs[page_number]),
                ),
                MediaBox=[
                    0,
                    0,
                    im.width * 72.0 / x_resolution,
                    im.height * 72.0 / y_resolution,
                ],
                Contents=contents_refs[page_number],
            )

            #
            # page contents

            page_contents = b"q %f 0 0 %f 0 0 cm /image Do Q\n" % (
                im.width * 72.0 / x_resolution,
                im.height * 72.0 / y_resolution,
            )

            existing_pdf.write_obj(contents_refs[page_number], stream=page_contents)

            page_number += 1

    #
    # trailer
    existing_pdf.write_xref_and_trailer()
    if hasattr(fp, "flush"):
        fp.flush()
    existing_pdf.close()


#
# --------------------------------------------------------------------


Image.register_save("PDF", _save)
Image.register_save_all("PDF", _save_all)

Image.register_extension("PDF", ".pdf")

Image.register_mime("PDF", "application/pdf")

```
--- END FILE ---

Please first localize the bug based on the issue statement, and then generate *SEARCH/REPLACE* edits to fix the issue.

Every *SEARCH/REPLACE* edit must use this format:
1. The file path
2. The start of search block: <<<<<<< SEARCH
3. A contiguous chunk of lines to search for in the existing source code
4. The dividing line: =======
5. The lines to replace into the source code
6. The end of the replace block: >>>>>>> REPLACE

Here is an example:

```python
### mathweb/flask/app.py
<<<<<<< SEARCH
from flask import Flask
=======
import math
from flask import Flask
>>>>>>> REPLACE
```
</solution>

Please note that the *SEARCH/REPLACE* edit REQUIRES PROPER INDENTATION. If you would like to add the line '        print(x)', you must fully write that out, with all those spaces before the code!
Wrap each *SEARCH/REPLACE* edit in a code block as shown in the example above. If you have multiple *SEARCH/REPLACE* edits, use a separate code block for each one.
user