{
    "file_diffs": [
        {
            "old_file_content": "from helper import unittest, PillowTestCase, hopper\nfrom PIL import Image, PdfParser\nimport io\nimport os\nimport os.path\nimport tempfile\n\n\nclass TestFilePdf(PillowTestCase):\n\n    def helper_save_as_pdf(self, mode, **kwargs):\n        # Arrange\n        im = hopper(mode)\n        outfile = self.tempfile(\"temp_\" + mode + \".pdf\")\n\n        # Act\n        im.save(outfile, **kwargs)\n\n        # Assert\n        self.assertTrue(os.path.isfile(outfile))\n        self.assertGreater(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                self.assertGreater(len(pdf.pages), 1)\n            else:\n                self.assertGreater(len(pdf.pages), 0)\n\n        return outfile\n\n    def test_monochrome(self):\n        # Arrange\n        mode = \"1\"\n\n        # Act / Assert\n        self.helper_save_as_pdf(mode)\n\n    def test_greyscale(self):\n        # Arrange\n        mode = \"L\"\n\n        # Act / Assert\n        self.helper_save_as_pdf(mode)\n\n    def test_rgb(self):\n        # Arrange\n        mode = \"RGB\"\n\n        # Act / Assert\n        self.helper_save_as_pdf(mode)\n\n    def test_p_mode(self):\n        # Arrange\n        mode = \"P\"\n\n        # Act / Assert\n        self.helper_save_as_pdf(mode)\n\n    def test_cmyk_mode(self):\n        # Arrange\n        mode = \"CMYK\"\n\n        # Act / Assert\n        self.helper_save_as_pdf(mode)\n\n    def test_unsupported_mode(self):\n        im = hopper(\"LA\")\n        outfile = self.tempfile(\"temp_LA.pdf\")\n\n        self.assertRaises(ValueError, im.save, outfile)\n\n    def test_save_all(self):\n        # Single frame image\n        self.helper_save_as_pdf(\"RGB\", save_all=True)\n\n        # Multiframe image\n        im = Image.open(\"Tests/images/dispose_bgnd.gif\")\n\n        outfile = self.tempfile('temp.pdf')\n        im.save(outfile, save_all=True)\n\n        self.assertTrue(os.path.isfile(outfile))\n        self.assertGreater(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        self.assertTrue(os.path.isfile(outfile))\n        self.assertGreater(os.path.getsize(outfile), 0)\n\n        # Test appending using a generator\n        def imGenerator(ims):\n            for im in ims:\n                yield im\n        im.save(outfile, save_all=True, append_images=imGenerator(ims))\n\n        self.assertTrue(os.path.isfile(outfile))\n        self.assertGreater(os.path.getsize(outfile), 0)\n\n        # Append JPEG images\n        jpeg = Image.open(\"Tests/images/flower.jpg\")\n        jpeg.save(outfile, save_all=True, append_images=[jpeg.copy()])\n\n        self.assertTrue(os.path.isfile(outfile))\n        self.assertGreater(os.path.getsize(outfile), 0)\n\n    def test_pdf_open(self):\n        # fail on a buffer full of null bytes\n        self.assertRaises(PdfParser.PdfFormatError, PdfParser.PdfParser, buf=bytearray(65536))\n\n        # make an empty PDF object\n        with PdfParser.PdfParser() as empty_pdf:\n            self.assertEqual(len(empty_pdf.pages), 0)\n            self.assertEqual(len(empty_pdf.info), 0)\n            self.assertFalse(empty_pdf.should_close_buf)\n            self.assertFalse(empty_pdf.should_close_file)\n\n        # make a PDF file\n        pdf_filename = self.helper_save_as_pdf(\"RGB\")\n\n        # open the PDF file\n        with PdfParser.PdfParser(filename=pdf_filename) as hopper_pdf:\n            self.assertEqual(len(hopper_pdf.pages), 1)\n            self.assertTrue(hopper_pdf.should_close_buf)\n            self.assertTrue(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            self.assertEqual(len(hopper_pdf.pages), 1)\n            self.assertFalse(hopper_pdf.should_close_buf)\n            self.assertFalse(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                self.assertEqual(len(hopper_pdf.pages), 1)\n                self.assertTrue(hopper_pdf.should_close_buf)\n                self.assertFalse(hopper_pdf.should_close_file)\n\n    def test_pdf_append_fails_on_nonexistent_file(self):\n        im = hopper(\"RGB\")\n        temp_dir = tempfile.mkdtemp()\n        try:\n            self.assertRaises(IOError, im.save, os.path.join(temp_dir, \"nonexistent.pdf\"), append=True)\n        finally:\n            os.rmdir(temp_dir)\n\n    def check_pdf_pages_consistency(self, pdf):\n        pages_info = pdf.read_indirect(pdf.pages_ref)\n        self.assertNotIn(b\"Parent\", pages_info)\n        self.assertIn(b\"Kids\", 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                self.assertIn(b\"Parent\", page_info)\n                page_ref = page_info[b\"Parent\"]\n                if page_ref == pdf.pages_ref:\n                    break\n            self.assertEqual(pdf.pages_ref, page_info[b\"Parent\"])\n        self.assertEqual(kids_not_used, [])\n\n    def test_pdf_append(self):\n        # make a PDF file\n        pdf_filename = self.helper_save_as_pdf(\"RGB\", producer=\"PdfParser\")\n\n        # open it, check pages and info\n        with PdfParser.PdfParser(pdf_filename, mode=\"r+b\") as pdf:\n            self.assertEqual(len(pdf.pages), 1)\n            self.assertEqual(len(pdf.info), 1)\n            self.assertEqual(pdf.info.Producer, \"PdfParser\")\n            self.check_pdf_pages_consistency(pdf)\n\n            # append some info\n            pdf.info.Title = \"abc\"\n            pdf.info.Author = \"def\"\n            pdf.info.Subject = u\"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            self.assertEqual(len(pdf.pages), 1)\n            self.assertEqual(len(pdf.info), 6)\n            self.assertEqual(pdf.info.Title, \"abc\")\n            self.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            self.assertEqual(len(pdf.pages), 3)\n            self.assertEqual(len(pdf.info), 6)\n            self.assertEqual(PdfParser.decode_text(pdf.info[b\"Title\"]), \"abc\")\n            self.assertEqual(pdf.info.Title, \"abc\")\n            self.assertEqual(pdf.info.Producer, \"PdfParser\")\n            self.assertEqual(pdf.info.Keywords, \"qw)e\\\\r(ty\")\n            self.assertEqual(pdf.info.Subject, u\"ghi\\uABCD\")\n            self.check_pdf_pages_consistency(pdf)\n\n    def test_pdf_info(self):\n        # make a PDF file\n        pdf_filename = self.helper_save_as_pdf(\"RGB\", title=\"title\", author=\"author\", subject=\"subject\", keywords=\"keywords\", creator=\"creator\", producer=\"producer\")\n\n        # open it, check pages and info\n        with PdfParser.PdfParser(pdf_filename) as pdf:\n            self.assertEqual(len(pdf.info), 6)\n            self.assertEqual(pdf.info.Title, \"title\")\n            self.assertEqual(pdf.info.Author, \"author\")\n            self.assertEqual(pdf.info.Subject, \"subject\")\n            self.assertEqual(pdf.info.Keywords, \"keywords\")\n            self.assertEqual(pdf.info.Creator, \"creator\")\n            self.assertEqual(pdf.info.Producer, \"producer\")\n            self.check_pdf_pages_consistency(pdf)\n\n    def test_pdf_append_to_bytesio(self):\n        im = hopper(\"RGB\")\n        f = io.BytesIO()\n        im.save(f, format=\"PDF\")\n        initial_size = len(f.getvalue())\n        self.assertGreater(initial_size, 0)\n        im = hopper(\"P\")\n        f = io.BytesIO(f.getvalue())\n        im.save(f, format=\"PDF\", append=True)\n        self.assertGreater(len(f.getvalue()), initial_size)\n\n\nif __name__ == '__main__':\n    unittest.main()\n",
            "new_file_content": "from helper import unittest, PillowTestCase, hopper\nfrom PIL import Image, PdfParser\nimport io\nimport os\nimport os.path\nimport tempfile\n\n\nclass TestFilePdf(PillowTestCase):\n\n    def helper_save_as_pdf(self, mode, **kwargs):\n        # Arrange\n        im = hopper(mode)\n        outfile = self.tempfile(\"temp_\" + mode + \".pdf\")\n\n        # Act\n        im.save(outfile, **kwargs)\n\n        # Assert\n        self.assertTrue(os.path.isfile(outfile))\n        self.assertGreater(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                self.assertGreater(len(pdf.pages), 1)\n            else:\n                self.assertGreater(len(pdf.pages), 0)\n\n        return outfile\n\n    def test_monochrome(self):\n        # Arrange\n        mode = \"1\"\n\n        # Act / Assert\n        self.helper_save_as_pdf(mode)\n\n    def test_greyscale(self):\n        # Arrange\n        mode = \"L\"\n\n        # Act / Assert\n        self.helper_save_as_pdf(mode)\n\n    def test_rgb(self):\n        # Arrange\n        mode = \"RGB\"\n\n        # Act / Assert\n        self.helper_save_as_pdf(mode)\n\n    def test_p_mode(self):\n        # Arrange\n        mode = \"P\"\n\n        # Act / Assert\n        self.helper_save_as_pdf(mode)\n\n    def test_cmyk_mode(self):\n        # Arrange\n        mode = \"CMYK\"\n\n        # Act / Assert\n        self.helper_save_as_pdf(mode)\n\n    def test_unsupported_mode(self):\n        im = hopper(\"LA\")\n        outfile = self.tempfile(\"temp_LA.pdf\")\n\n        self.assertRaises(ValueError, im.save, outfile)\n\n    def test_save_all(self):\n        # Single frame image\n        self.helper_save_as_pdf(\"RGB\", save_all=True)\n\n        # Multiframe image\n        im = Image.open(\"Tests/images/dispose_bgnd.gif\")\n\n        outfile = self.tempfile('temp.pdf')\n        im.save(outfile, save_all=True)\n\n        self.assertTrue(os.path.isfile(outfile))\n        self.assertGreater(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        self.assertTrue(os.path.isfile(outfile))\n        self.assertGreater(os.path.getsize(outfile), 0)\n\n        # Test appending using a generator\n        def imGenerator(ims):\n            for im in ims:\n                yield im\n        im.save(outfile, save_all=True, append_images=imGenerator(ims))\n\n        self.assertTrue(os.path.isfile(outfile))\n        self.assertGreater(os.path.getsize(outfile), 0)\n\n        # Append JPEG images\n        jpeg = Image.open(\"Tests/images/flower.jpg\")\n        jpeg.save(outfile, save_all=True, append_images=[jpeg.copy()])\n\n        self.assertTrue(os.path.isfile(outfile))\n        self.assertGreater(os.path.getsize(outfile), 0)\n\n    def test_multiframe_normal_save(self):\n        # Test saving a multiframe image without save_all\n        im = Image.open(\"Tests/images/dispose_bgnd.gif\")\n\n        outfile = self.tempfile('temp.pdf')\n        im.save(outfile)\n\n        self.assertTrue(os.path.isfile(outfile))\n        self.assertGreater(os.path.getsize(outfile), 0)\n\n    def test_pdf_open(self):\n        # fail on a buffer full of null bytes\n        self.assertRaises(PdfParser.PdfFormatError, PdfParser.PdfParser, buf=bytearray(65536))\n\n        # make an empty PDF object\n        with PdfParser.PdfParser() as empty_pdf:\n            self.assertEqual(len(empty_pdf.pages), 0)\n            self.assertEqual(len(empty_pdf.info), 0)\n            self.assertFalse(empty_pdf.should_close_buf)\n            self.assertFalse(empty_pdf.should_close_file)\n\n        # make a PDF file\n        pdf_filename = self.helper_save_as_pdf(\"RGB\")\n\n        # open the PDF file\n        with PdfParser.PdfParser(filename=pdf_filename) as hopper_pdf:\n            self.assertEqual(len(hopper_pdf.pages), 1)\n            self.assertTrue(hopper_pdf.should_close_buf)\n            self.assertTrue(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            self.assertEqual(len(hopper_pdf.pages), 1)\n            self.assertFalse(hopper_pdf.should_close_buf)\n            self.assertFalse(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                self.assertEqual(len(hopper_pdf.pages), 1)\n                self.assertTrue(hopper_pdf.should_close_buf)\n                self.assertFalse(hopper_pdf.should_close_file)\n\n    def test_pdf_append_fails_on_nonexistent_file(self):\n        im = hopper(\"RGB\")\n        temp_dir = tempfile.mkdtemp()\n        try:\n            self.assertRaises(IOError, im.save, os.path.join(temp_dir, \"nonexistent.pdf\"), append=True)\n        finally:\n            os.rmdir(temp_dir)\n\n    def check_pdf_pages_consistency(self, pdf):\n        pages_info = pdf.read_indirect(pdf.pages_ref)\n        self.assertNotIn(b\"Parent\", pages_info)\n        self.assertIn(b\"Kids\", 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                self.assertIn(b\"Parent\", page_info)\n                page_ref = page_info[b\"Parent\"]\n                if page_ref == pdf.pages_ref:\n                    break\n            self.assertEqual(pdf.pages_ref, page_info[b\"Parent\"])\n        self.assertEqual(kids_not_used, [])\n\n    def test_pdf_append(self):\n        # make a PDF file\n        pdf_filename = self.helper_save_as_pdf(\"RGB\", producer=\"PdfParser\")\n\n        # open it, check pages and info\n        with PdfParser.PdfParser(pdf_filename, mode=\"r+b\") as pdf:\n            self.assertEqual(len(pdf.pages), 1)\n            self.assertEqual(len(pdf.info), 1)\n            self.assertEqual(pdf.info.Producer, \"PdfParser\")\n            self.check_pdf_pages_consistency(pdf)\n\n            # append some info\n            pdf.info.Title = \"abc\"\n            pdf.info.Author = \"def\"\n            pdf.info.Subject = u\"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            self.assertEqual(len(pdf.pages), 1)\n            self.assertEqual(len(pdf.info), 6)\n            self.assertEqual(pdf.info.Title, \"abc\")\n            self.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            self.assertEqual(len(pdf.pages), 3)\n            self.assertEqual(len(pdf.info), 6)\n            self.assertEqual(PdfParser.decode_text(pdf.info[b\"Title\"]), \"abc\")\n            self.assertEqual(pdf.info.Title, \"abc\")\n            self.assertEqual(pdf.info.Producer, \"PdfParser\")\n            self.assertEqual(pdf.info.Keywords, \"qw)e\\\\r(ty\")\n            self.assertEqual(pdf.info.Subject, u\"ghi\\uABCD\")\n            self.check_pdf_pages_consistency(pdf)\n\n    def test_pdf_info(self):\n        # make a PDF file\n        pdf_filename = self.helper_save_as_pdf(\"RGB\", title=\"title\", author=\"author\", subject=\"subject\", keywords=\"keywords\", creator=\"creator\", producer=\"producer\")\n\n        # open it, check pages and info\n        with PdfParser.PdfParser(pdf_filename) as pdf:\n            self.assertEqual(len(pdf.info), 6)\n            self.assertEqual(pdf.info.Title, \"title\")\n            self.assertEqual(pdf.info.Author, \"author\")\n            self.assertEqual(pdf.info.Subject, \"subject\")\n            self.assertEqual(pdf.info.Keywords, \"keywords\")\n            self.assertEqual(pdf.info.Creator, \"creator\")\n            self.assertEqual(pdf.info.Producer, \"producer\")\n            self.check_pdf_pages_consistency(pdf)\n\n    def test_pdf_append_to_bytesio(self):\n        im = hopper(\"RGB\")\n        f = io.BytesIO()\n        im.save(f, format=\"PDF\")\n        initial_size = len(f.getvalue())\n        self.assertGreater(initial_size, 0)\n        im = hopper(\"P\")\n        f = io.BytesIO(f.getvalue())\n        im.save(f, format=\"PDF\", append=True)\n        self.assertGreater(len(f.getvalue()), initial_size)\n\n\nif __name__ == '__main__':\n    unittest.main()\n",
            "header": {
                "file": {
                    "path": "Tests/test_file_pdf.py"
                },
                "misc_line": null
            },
            "index_line": {
                "old_commit_hash": "f17da8d74",
                "new_commit_hash": "3d359f445",
                "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": 104,
                            "length": 6
                        },
                        "new_range": {
                            "start": 104,
                            "length": 16
                        },
                        "section": "class TestFilePdf(PillowTestCase):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "        self.assertTrue(os.path.isfile(outfile))",
                                "type": "context"
                            },
                            {
                                "content": "        self.assertGreater(os.path.getsize(outfile), 0)",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "    def test_multiframe_normal_save(self):",
                                "type": "added"
                            },
                            {
                                "content": "        # Test saving a multiframe image without save_all",
                                "type": "added"
                            },
                            {
                                "content": "        im = Image.open(\"Tests/images/dispose_bgnd.gif\")",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "        outfile = self.tempfile('temp.pdf')",
                                "type": "added"
                            },
                            {
                                "content": "        im.save(outfile)",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "        self.assertTrue(os.path.isfile(outfile))",
                                "type": "added"
                            },
                            {
                                "content": "        self.assertGreater(os.path.getsize(outfile), 0)",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "    def test_pdf_open(self):",
                                "type": "context"
                            },
                            {
                                "content": "        # fail on a buffer full of null bytes",
                                "type": "context"
                            },
                            {
                                "content": "        self.assertRaises(PdfParser.PdfFormatError, PdfParser.PdfParser, buf=bytearray(65536))",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "Tests/test_file_pdf.py",
                            "type": "class",
                            "name": "TestFilePdf",
                            "content": "class TestFilePdf(PillowTestCase):\n\n    def helper_save_as_pdf(self, mode, **kwargs):\n        # Arrange\n        im = hopper(mode)\n        outfile = self.tempfile(\"temp_\" + mode + \".pdf\")\n\n        # Act\n        im.save(outfile, **kwargs)\n\n        # Assert\n        self.assertTrue(os.path.isfile(outfile))\n        self.assertGreater(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                self.assertGreater(len(pdf.pages), 1)\n            else:\n                self.assertGreater(len(pdf.pages), 0)\n\n        return outfile\n\n    def test_monochrome(self):\n        # Arrange\n        mode = \"1\"\n\n        # Act / Assert\n        self.helper_save_as_pdf(mode)\n\n    def test_greyscale(self):\n        # Arrange\n        mode = \"L\"\n\n        # Act / Assert\n        self.helper_save_as_pdf(mode)\n\n    def test_rgb(self):\n        # Arrange\n        mode = \"RGB\"\n\n        # Act / Assert\n        self.helper_save_as_pdf(mode)\n\n    def test_p_mode(self):\n        # Arrange\n        mode = \"P\"\n\n        # Act / Assert\n        self.helper_save_as_pdf(mode)\n\n    def test_cmyk_mode(self):\n        # Arrange\n        mode = \"CMYK\"\n\n        # Act / Assert\n        self.helper_save_as_pdf(mode)\n\n    def test_unsupported_mode(self):\n        im = hopper(\"LA\")\n        outfile = self.tempfile(\"temp_LA.pdf\")\n\n        self.assertRaises(ValueError, im.save, outfile)\n\n    def test_save_all(self):\n        # Single frame image\n        self.helper_save_as_pdf(\"RGB\", save_all=True)\n\n        # Multiframe image\n        im = Image.open(\"Tests/images/dispose_bgnd.gif\")\n\n        outfile = self.tempfile('temp.pdf')\n        im.save(outfile, save_all=True)\n\n        self.assertTrue(os.path.isfile(outfile))\n        self.assertGreater(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        self.assertTrue(os.path.isfile(outfile))\n        self.assertGreater(os.path.getsize(outfile), 0)\n\n        # Test appending using a generator\n        def imGenerator(ims):\n            for im in ims:\n                yield im\n        im.save(outfile, save_all=True, append_images=imGenerator(ims))\n\n        self.assertTrue(os.path.isfile(outfile))\n        self.assertGreater(os.path.getsize(outfile), 0)\n\n        # Append JPEG images\n        jpeg = Image.open(\"Tests/images/flower.jpg\")\n        jpeg.save(outfile, save_all=True, append_images=[jpeg.copy()])\n\n        self.assertTrue(os.path.isfile(outfile))\n        self.assertGreater(os.path.getsize(outfile), 0)\n\n    def test_multiframe_normal_save(self):\n        # Test saving a multiframe image without save_all\n        im = Image.open(\"Tests/images/dispose_bgnd.gif\")\n\n        outfile = self.tempfile('temp.pdf')\n        im.save(outfile)\n\n        self.assertTrue(os.path.isfile(outfile))\n        self.assertGreater(os.path.getsize(outfile), 0)\n\n    def test_pdf_open(self):\n        # fail on a buffer full of null bytes\n        self.assertRaises(PdfParser.PdfFormatError, PdfParser.PdfParser, buf=bytearray(65536))\n\n        # make an empty PDF object\n        with PdfParser.PdfParser() as empty_pdf:\n            self.assertEqual(len(empty_pdf.pages), 0)\n            self.assertEqual(len(empty_pdf.info), 0)\n            self.assertFalse(empty_pdf.should_close_buf)\n            self.assertFalse(empty_pdf.should_close_file)\n\n        # make a PDF file\n        pdf_filename = self.helper_save_as_pdf(\"RGB\")\n\n        # open the PDF file\n        with PdfParser.PdfParser(filename=pdf_filename) as hopper_pdf:\n            self.assertEqual(len(hopper_pdf.pages), 1)\n            self.assertTrue(hopper_pdf.should_close_buf)\n            self.assertTrue(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            self.assertEqual(len(hopper_pdf.pages), 1)\n            self.assertFalse(hopper_pdf.should_close_buf)\n            self.assertFalse(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                self.assertEqual(len(hopper_pdf.pages), 1)\n                self.assertTrue(hopper_pdf.should_close_buf)\n                self.assertFalse(hopper_pdf.should_close_file)\n\n    def test_pdf_append_fails_on_nonexistent_file(self):\n        im = hopper(\"RGB\")\n        temp_dir = tempfile.mkdtemp()\n        try:\n            self.assertRaises(IOError, im.save, os.path.join(temp_dir, \"nonexistent.pdf\"), append=True)\n        finally:\n            os.rmdir(temp_dir)\n\n    def check_pdf_pages_consistency(self, pdf):\n        pages_info = pdf.read_indirect(pdf.pages_ref)\n        self.assertNotIn(b\"Parent\", pages_info)\n        self.assertIn(b\"Kids\", 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                self.assertIn(b\"Parent\", page_info)\n                page_ref = page_info[b\"Parent\"]\n                if page_ref == pdf.pages_ref:\n                    break\n            self.assertEqual(pdf.pages_ref, page_info[b\"Parent\"])\n        self.assertEqual(kids_not_used, [])\n\n    def test_pdf_append(self):\n        # make a PDF file\n        pdf_filename = self.helper_save_as_pdf(\"RGB\", producer=\"PdfParser\")\n\n        # open it, check pages and info\n        with PdfParser.PdfParser(pdf_filename, mode=\"r+b\") as pdf:\n            self.assertEqual(len(pdf.pages), 1)\n            self.assertEqual(len(pdf.info), 1)\n            self.assertEqual(pdf.info.Producer, \"PdfParser\")\n            self.check_pdf_pages_consistency(pdf)\n\n            # append some info\n            pdf.info.Title = \"abc\"\n            pdf.info.Author = \"def\"\n            pdf.info.Subject = u\"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            self.assertEqual(len(pdf.pages), 1)\n            self.assertEqual(len(pdf.info), 6)\n            self.assertEqual(pdf.info.Title, \"abc\")\n            self.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            self.assertEqual(len(pdf.pages), 3)\n            self.assertEqual(len(pdf.info), 6)\n            self.assertEqual(PdfParser.decode_text(pdf.info[b\"Title\"]), \"abc\")\n            self.assertEqual(pdf.info.Title, \"abc\")\n            self.assertEqual(pdf.info.Producer, \"PdfParser\")\n            self.assertEqual(pdf.info.Keywords, \"qw)e\\\\r(ty\")\n            self.assertEqual(pdf.info.Subject, u\"ghi\\uABCD\")\n            self.check_pdf_pages_consistency(pdf)\n\n    def test_pdf_info(self):\n        # make a PDF file\n        pdf_filename = self.helper_save_as_pdf(\"RGB\", title=\"title\", author=\"author\", subject=\"subject\", keywords=\"keywords\", creator=\"creator\", producer=\"producer\")\n\n        # open it, check pages and info\n        with PdfParser.PdfParser(pdf_filename) as pdf:\n            self.assertEqual(len(pdf.info), 6)\n            self.assertEqual(pdf.info.Title, \"title\")\n            self.assertEqual(pdf.info.Author, \"author\")\n            self.assertEqual(pdf.info.Subject, \"subject\")\n            self.assertEqual(pdf.info.Keywords, \"keywords\")\n            self.assertEqual(pdf.info.Creator, \"creator\")\n            self.assertEqual(pdf.info.Producer, \"producer\")\n            self.check_pdf_pages_consistency(pdf)\n\n    def test_pdf_append_to_bytesio(self):\n        im = hopper(\"RGB\")\n        f = io.BytesIO()\n        im.save(f, format=\"PDF\")\n        initial_size = len(f.getvalue())\n        self.assertGreater(initial_size, 0)\n        im = hopper(\"P\")\n        f = io.BytesIO(f.getvalue())\n        im.save(f, format=\"PDF\", append=True)\n        self.assertGreater(len(f.getvalue()), initial_size)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 9,
                            "end_lineno": 244,
                            "parent": null
                        }
                    ],
                    "added_entities": [
                        {
                            "file_name": "Tests/test_file_pdf.py",
                            "type": "method",
                            "name": "TestFilePdf.test_multiframe_normal_save",
                            "content": "class TestFilePdf(PillowTestCase):\n\n    def helper_save_as_pdf(self, mode, **kwargs):\n        # Arrange\n        im = hopper(mode)\n        outfile = self.tempfile(\"temp_\" + mode + \".pdf\")\n\n        # Act\n        im.save(outfile, **kwargs)\n\n        # Assert\n        self.assertTrue(os.path.isfile(outfile))\n        self.assertGreater(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                self.assertGreater(len(pdf.pages), 1)\n            else:\n                self.assertGreater(len(pdf.pages), 0)\n\n        return outfile\n\n    def test_monochrome(self):\n        # Arrange\n        mode = \"1\"\n\n        # Act / Assert\n        self.helper_save_as_pdf(mode)\n\n    def test_greyscale(self):\n        # Arrange\n        mode = \"L\"\n\n        # Act / Assert\n        self.helper_save_as_pdf(mode)\n\n    def test_rgb(self):\n        # Arrange\n        mode = \"RGB\"\n\n        # Act / Assert\n        self.helper_save_as_pdf(mode)\n\n    def test_p_mode(self):\n        # Arrange\n        mode = \"P\"\n\n        # Act / Assert\n        self.helper_save_as_pdf(mode)\n\n    def test_cmyk_mode(self):\n        # Arrange\n        mode = \"CMYK\"\n\n        # Act / Assert\n        self.helper_save_as_pdf(mode)\n\n    def test_unsupported_mode(self):\n        im = hopper(\"LA\")\n        outfile = self.tempfile(\"temp_LA.pdf\")\n\n        self.assertRaises(ValueError, im.save, outfile)\n\n    def test_save_all(self):\n        # Single frame image\n        self.helper_save_as_pdf(\"RGB\", save_all=True)\n\n        # Multiframe image\n        im = Image.open(\"Tests/images/dispose_bgnd.gif\")\n\n        outfile = self.tempfile('temp.pdf')\n        im.save(outfile, save_all=True)\n\n        self.assertTrue(os.path.isfile(outfile))\n        self.assertGreater(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        self.assertTrue(os.path.isfile(outfile))\n        self.assertGreater(os.path.getsize(outfile), 0)\n\n        # Test appending using a generator\n        def imGenerator(ims):\n            for im in ims:\n                yield im\n        im.save(outfile, save_all=True, append_images=imGenerator(ims))\n\n        self.assertTrue(os.path.isfile(outfile))\n        self.assertGreater(os.path.getsize(outfile), 0)\n\n        # Append JPEG images\n        jpeg = Image.open(\"Tests/images/flower.jpg\")\n        jpeg.save(outfile, save_all=True, append_images=[jpeg.copy()])\n\n        self.assertTrue(os.path.isfile(outfile))\n        self.assertGreater(os.path.getsize(outfile), 0)\n\n    def test_multiframe_normal_save(self):\n        # Test saving a multiframe image without save_all\n        im = Image.open(\"Tests/images/dispose_bgnd.gif\")\n\n        outfile = self.tempfile('temp.pdf')\n        im.save(outfile)\n\n        self.assertTrue(os.path.isfile(outfile))\n        self.assertGreater(os.path.getsize(outfile), 0)\n\n    def test_pdf_open(self):\n        # fail on a buffer full of null bytes\n        self.assertRaises(PdfParser.PdfFormatError, PdfParser.PdfParser, buf=bytearray(65536))\n\n        # make an empty PDF object\n        with PdfParser.PdfParser() as empty_pdf:\n            self.assertEqual(len(empty_pdf.pages), 0)\n            self.assertEqual(len(empty_pdf.info), 0)\n            self.assertFalse(empty_pdf.should_close_buf)\n            self.assertFalse(empty_pdf.should_close_file)\n\n        # make a PDF file\n        pdf_filename = self.helper_save_as_pdf(\"RGB\")\n\n        # open the PDF file\n        with PdfParser.PdfParser(filename=pdf_filename) as hopper_pdf:\n            self.assertEqual(len(hopper_pdf.pages), 1)\n            self.assertTrue(hopper_pdf.should_close_buf)\n            self.assertTrue(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            self.assertEqual(len(hopper_pdf.pages), 1)\n            self.assertFalse(hopper_pdf.should_close_buf)\n            self.assertFalse(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                self.assertEqual(len(hopper_pdf.pages), 1)\n                self.assertTrue(hopper_pdf.should_close_buf)\n                self.assertFalse(hopper_pdf.should_close_file)\n\n    def test_pdf_append_fails_on_nonexistent_file(self):\n        im = hopper(\"RGB\")\n        temp_dir = tempfile.mkdtemp()\n        try:\n            self.assertRaises(IOError, im.save, os.path.join(temp_dir, \"nonexistent.pdf\"), append=True)\n        finally:\n            os.rmdir(temp_dir)\n\n    def check_pdf_pages_consistency(self, pdf):\n        pages_info = pdf.read_indirect(pdf.pages_ref)\n        self.assertNotIn(b\"Parent\", pages_info)\n        self.assertIn(b\"Kids\", 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                self.assertIn(b\"Parent\", page_info)\n                page_ref = page_info[b\"Parent\"]\n                if page_ref == pdf.pages_ref:\n                    break\n            self.assertEqual(pdf.pages_ref, page_info[b\"Parent\"])\n        self.assertEqual(kids_not_used, [])\n\n    def test_pdf_append(self):\n        # make a PDF file\n        pdf_filename = self.helper_save_as_pdf(\"RGB\", producer=\"PdfParser\")\n\n        # open it, check pages and info\n        with PdfParser.PdfParser(pdf_filename, mode=\"r+b\") as pdf:\n            self.assertEqual(len(pdf.pages), 1)\n            self.assertEqual(len(pdf.info), 1)\n            self.assertEqual(pdf.info.Producer, \"PdfParser\")\n            self.check_pdf_pages_consistency(pdf)\n\n            # append some info\n            pdf.info.Title = \"abc\"\n            pdf.info.Author = \"def\"\n            pdf.info.Subject = u\"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            self.assertEqual(len(pdf.pages), 1)\n            self.assertEqual(len(pdf.info), 6)\n            self.assertEqual(pdf.info.Title, \"abc\")\n            self.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            self.assertEqual(len(pdf.pages), 3)\n            self.assertEqual(len(pdf.info), 6)\n            self.assertEqual(PdfParser.decode_text(pdf.info[b\"Title\"]), \"abc\")\n            self.assertEqual(pdf.info.Title, \"abc\")\n            self.assertEqual(pdf.info.Producer, \"PdfParser\")\n            self.assertEqual(pdf.info.Keywords, \"qw)e\\\\r(ty\")\n            self.assertEqual(pdf.info.Subject, u\"ghi\\uABCD\")\n            self.check_pdf_pages_consistency(pdf)\n\n    def test_pdf_info(self):\n        # make a PDF file\n        pdf_filename = self.helper_save_as_pdf(\"RGB\", title=\"title\", author=\"author\", subject=\"subject\", keywords=\"keywords\", creator=\"creator\", producer=\"producer\")\n\n        # open it, check pages and info\n        with PdfParser.PdfParser(pdf_filename) as pdf:\n            self.assertEqual(len(pdf.info), 6)\n            self.assertEqual(pdf.info.Title, \"title\")\n            self.assertEqual(pdf.info.Author, \"author\")\n            self.assertEqual(pdf.info.Subject, \"subject\")\n            self.assertEqual(pdf.info.Keywords, \"keywords\")\n            self.assertEqual(pdf.info.Creator, \"creator\")\n            self.assertEqual(pdf.info.Producer, \"producer\")\n            self.check_pdf_pages_consistency(pdf)\n\n    def test_pdf_append_to_bytesio(self):\n        im = hopper(\"RGB\")\n        f = io.BytesIO()\n        im.save(f, format=\"PDF\")\n        initial_size = len(f.getvalue())\n        self.assertGreater(initial_size, 0)\n        im = hopper(\"P\")\n        f = io.BytesIO(f.getvalue())\n        im.save(f, format=\"PDF\", append=True)\n        self.assertGreater(len(f.getvalue()), initial_size)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 107,
                            "end_lineno": 115,
                            "parent": {
                                "file_name": "Tests/test_file_pdf.py",
                                "type": "class",
                                "name": "TestFilePdf",
                                "content": "class TestFilePdf(PillowTestCase):\n\n    def helper_save_as_pdf(self, mode, **kwargs):\n        # Arrange\n        im = hopper(mode)\n        outfile = self.tempfile(\"temp_\" + mode + \".pdf\")\n\n        # Act\n        im.save(outfile, **kwargs)\n\n        # Assert\n        self.assertTrue(os.path.isfile(outfile))\n        self.assertGreater(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                self.assertGreater(len(pdf.pages), 1)\n            else:\n                self.assertGreater(len(pdf.pages), 0)\n\n        return outfile\n\n    def test_monochrome(self):\n        # Arrange\n        mode = \"1\"\n\n        # Act / Assert\n        self.helper_save_as_pdf(mode)\n\n    def test_greyscale(self):\n        # Arrange\n        mode = \"L\"\n\n        # Act / Assert\n        self.helper_save_as_pdf(mode)\n\n    def test_rgb(self):\n        # Arrange\n        mode = \"RGB\"\n\n        # Act / Assert\n        self.helper_save_as_pdf(mode)\n\n    def test_p_mode(self):\n        # Arrange\n        mode = \"P\"\n\n        # Act / Assert\n        self.helper_save_as_pdf(mode)\n\n    def test_cmyk_mode(self):\n        # Arrange\n        mode = \"CMYK\"\n\n        # Act / Assert\n        self.helper_save_as_pdf(mode)\n\n    def test_unsupported_mode(self):\n        im = hopper(\"LA\")\n        outfile = self.tempfile(\"temp_LA.pdf\")\n\n        self.assertRaises(ValueError, im.save, outfile)\n\n    def test_save_all(self):\n        # Single frame image\n        self.helper_save_as_pdf(\"RGB\", save_all=True)\n\n        # Multiframe image\n        im = Image.open(\"Tests/images/dispose_bgnd.gif\")\n\n        outfile = self.tempfile('temp.pdf')\n        im.save(outfile, save_all=True)\n\n        self.assertTrue(os.path.isfile(outfile))\n        self.assertGreater(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        self.assertTrue(os.path.isfile(outfile))\n        self.assertGreater(os.path.getsize(outfile), 0)\n\n        # Test appending using a generator\n        def imGenerator(ims):\n            for im in ims:\n                yield im\n        im.save(outfile, save_all=True, append_images=imGenerator(ims))\n\n        self.assertTrue(os.path.isfile(outfile))\n        self.assertGreater(os.path.getsize(outfile), 0)\n\n        # Append JPEG images\n        jpeg = Image.open(\"Tests/images/flower.jpg\")\n        jpeg.save(outfile, save_all=True, append_images=[jpeg.copy()])\n\n        self.assertTrue(os.path.isfile(outfile))\n        self.assertGreater(os.path.getsize(outfile), 0)\n\n    def test_multiframe_normal_save(self):\n        # Test saving a multiframe image without save_all\n        im = Image.open(\"Tests/images/dispose_bgnd.gif\")\n\n        outfile = self.tempfile('temp.pdf')\n        im.save(outfile)\n\n        self.assertTrue(os.path.isfile(outfile))\n        self.assertGreater(os.path.getsize(outfile), 0)\n\n    def test_pdf_open(self):\n        # fail on a buffer full of null bytes\n        self.assertRaises(PdfParser.PdfFormatError, PdfParser.PdfParser, buf=bytearray(65536))\n\n        # make an empty PDF object\n        with PdfParser.PdfParser() as empty_pdf:\n            self.assertEqual(len(empty_pdf.pages), 0)\n            self.assertEqual(len(empty_pdf.info), 0)\n            self.assertFalse(empty_pdf.should_close_buf)\n            self.assertFalse(empty_pdf.should_close_file)\n\n        # make a PDF file\n        pdf_filename = self.helper_save_as_pdf(\"RGB\")\n\n        # open the PDF file\n        with PdfParser.PdfParser(filename=pdf_filename) as hopper_pdf:\n            self.assertEqual(len(hopper_pdf.pages), 1)\n            self.assertTrue(hopper_pdf.should_close_buf)\n            self.assertTrue(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            self.assertEqual(len(hopper_pdf.pages), 1)\n            self.assertFalse(hopper_pdf.should_close_buf)\n            self.assertFalse(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                self.assertEqual(len(hopper_pdf.pages), 1)\n                self.assertTrue(hopper_pdf.should_close_buf)\n                self.assertFalse(hopper_pdf.should_close_file)\n\n    def test_pdf_append_fails_on_nonexistent_file(self):\n        im = hopper(\"RGB\")\n        temp_dir = tempfile.mkdtemp()\n        try:\n            self.assertRaises(IOError, im.save, os.path.join(temp_dir, \"nonexistent.pdf\"), append=True)\n        finally:\n            os.rmdir(temp_dir)\n\n    def check_pdf_pages_consistency(self, pdf):\n        pages_info = pdf.read_indirect(pdf.pages_ref)\n        self.assertNotIn(b\"Parent\", pages_info)\n        self.assertIn(b\"Kids\", 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                self.assertIn(b\"Parent\", page_info)\n                page_ref = page_info[b\"Parent\"]\n                if page_ref == pdf.pages_ref:\n                    break\n            self.assertEqual(pdf.pages_ref, page_info[b\"Parent\"])\n        self.assertEqual(kids_not_used, [])\n\n    def test_pdf_append(self):\n        # make a PDF file\n        pdf_filename = self.helper_save_as_pdf(\"RGB\", producer=\"PdfParser\")\n\n        # open it, check pages and info\n        with PdfParser.PdfParser(pdf_filename, mode=\"r+b\") as pdf:\n            self.assertEqual(len(pdf.pages), 1)\n            self.assertEqual(len(pdf.info), 1)\n            self.assertEqual(pdf.info.Producer, \"PdfParser\")\n            self.check_pdf_pages_consistency(pdf)\n\n            # append some info\n            pdf.info.Title = \"abc\"\n            pdf.info.Author = \"def\"\n            pdf.info.Subject = u\"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            self.assertEqual(len(pdf.pages), 1)\n            self.assertEqual(len(pdf.info), 6)\n            self.assertEqual(pdf.info.Title, \"abc\")\n            self.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            self.assertEqual(len(pdf.pages), 3)\n            self.assertEqual(len(pdf.info), 6)\n            self.assertEqual(PdfParser.decode_text(pdf.info[b\"Title\"]), \"abc\")\n            self.assertEqual(pdf.info.Title, \"abc\")\n            self.assertEqual(pdf.info.Producer, \"PdfParser\")\n            self.assertEqual(pdf.info.Keywords, \"qw)e\\\\r(ty\")\n            self.assertEqual(pdf.info.Subject, u\"ghi\\uABCD\")\n            self.check_pdf_pages_consistency(pdf)\n\n    def test_pdf_info(self):\n        # make a PDF file\n        pdf_filename = self.helper_save_as_pdf(\"RGB\", title=\"title\", author=\"author\", subject=\"subject\", keywords=\"keywords\", creator=\"creator\", producer=\"producer\")\n\n        # open it, check pages and info\n        with PdfParser.PdfParser(pdf_filename) as pdf:\n            self.assertEqual(len(pdf.info), 6)\n            self.assertEqual(pdf.info.Title, \"title\")\n            self.assertEqual(pdf.info.Author, \"author\")\n            self.assertEqual(pdf.info.Subject, \"subject\")\n            self.assertEqual(pdf.info.Keywords, \"keywords\")\n            self.assertEqual(pdf.info.Creator, \"creator\")\n            self.assertEqual(pdf.info.Producer, \"producer\")\n            self.check_pdf_pages_consistency(pdf)\n\n    def test_pdf_append_to_bytesio(self):\n        im = hopper(\"RGB\")\n        f = io.BytesIO()\n        im.save(f, format=\"PDF\")\n        initial_size = len(f.getvalue())\n        self.assertGreater(initial_size, 0)\n        im = hopper(\"P\")\n        f = io.BytesIO(f.getvalue())\n        im.save(f, format=\"PDF\", append=True)\n        self.assertGreater(len(f.getvalue()), initial_size)",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 9,
                                "end_lineno": 244,
                                "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\nfrom . import Image, ImageFile, ImageSequence, PdfParser\nimport io\n\n__version__ = \"0.5\"\n\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\ndef _save(im, fp, filename, save_all=False):\n    resolution = im.encoderinfo.get(\"resolution\", 72.0)\n    is_appending = im.encoderinfo.get(\"append\", False)\n    title = im.encoderinfo.get(\"title\", None)\n    author = im.encoderinfo.get(\"author\", None)\n    subject = im.encoderinfo.get(\"subject\", None)\n    keywords = im.encoderinfo.get(\"keywords\", None)\n    creator = im.encoderinfo.get(\"creator\", None)\n    producer = im.encoderinfo.get(\"producer\", None)\n\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    if title:\n        existing_pdf.info.Title = title\n    if author:\n        existing_pdf.info.Author = author\n    if subject:\n        existing_pdf.info.Subject = subject\n    if keywords:\n        existing_pdf.info.Keywords = keywords\n    if creator:\n        existing_pdf.info.Creator = creator\n    if producer:\n        existing_pdf.info.Producer = producer\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(\"created by PIL PDF driver \" + __version__)\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    numberOfPages = 0\n    image_refs = []\n    page_refs = []\n    contents_refs = []\n    for im in ims:\n        im_numberOfPages = 1\n        if save_all:\n            try:\n                im_numberOfPages = im.n_frames\n            except AttributeError:\n                # Image format does not have n_frames. It is a single frame image\n                pass\n        numberOfPages += im_numberOfPages\n        for i in range(im_numberOfPages):\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    pageNumber = 0\n    for imSequence in ims:\n        for im in ImageSequence.Iterator(imSequence):\n            # FIXME: Should replace ASCIIHexDecode with RunLengthDecode (packbits)\n            # or LZWDecode (tiff/lzw compression).  Note that PDF 1.2 also supports\n            # Flatedecode (zip compression).\n\n            bits = 8\n            params = None\n\n            if im.mode == \"1\":\n                filter = \"ASCIIHexDecode\"\n                colorspace = PdfParser.PdfName(\"DeviceGray\")\n                procset = \"ImageB\"  # grayscale\n                bits = 1\n            elif im.mode == \"L\":\n                filter = \"DCTDecode\"\n                # params = \"<< /Predictor 15 /Columns %d >>\" % (width-2)\n                colorspace = PdfParser.PdfName(\"DeviceGray\")\n                procset = \"ImageB\"  # grayscale\n            elif im.mode == \"P\":\n                filter = \"ASCIIHexDecode\"\n                palette = im.im.getpalette(\"RGB\")\n                colorspace = [PdfParser.PdfName(\"Indexed\"), PdfParser.PdfName(\"DeviceRGB\"), 255, PdfParser.PdfBinary(palette)]\n                procset = \"ImageI\"  # indexed color\n            elif im.mode == \"RGB\":\n                filter = \"DCTDecode\"\n                colorspace = PdfParser.PdfName(\"DeviceRGB\")\n                procset = \"ImageC\"  # color images\n            elif im.mode == \"CMYK\":\n                filter = \"DCTDecode\"\n                colorspace = PdfParser.PdfName(\"DeviceCMYK\")\n                procset = \"ImageC\"  # color images\n            else:\n                raise ValueError(\"cannot save mode %s\" % im.mode)\n\n            #\n            # image\n\n            op = io.BytesIO()\n\n            if filter == \"ASCIIHexDecode\":\n                if bits == 1:\n                    # FIXME: the hex encoder doesn't support packed 1-bit\n                    # images; do things the hard way...\n                    data = im.tobytes(\"raw\", \"1\")\n                    im = Image.new(\"L\", (len(data), 1), None)\n                    im.putdata(data)\n                ImageFile._save(im, op, [(\"hex\", (0, 0)+im.size, 0, im.mode)])\n            elif filter == \"DCTDecode\":\n                Image.SAVE[\"JPEG\"](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                raise ValueError(\"unsupported PDF filter (%s)\" % filter)\n\n            #\n            # Get image characteristics\n\n            width, height = im.size\n\n            existing_pdf.write_obj(image_refs[pageNumber], stream=op.getvalue(),\n                Type=PdfParser.PdfName(\"XObject\"),\n                Subtype=PdfParser.PdfName(\"Image\"),\n                Width=width,  # * 72.0 / resolution,\n                Height=height,  # * 72.0 / resolution,\n                Filter=PdfParser.PdfName(filter),\n                BitsPerComponent=bits,\n                DecodeParams=params,\n                ColorSpace=colorspace)\n\n            #\n            # page\n\n            existing_pdf.write_page(page_refs[pageNumber],\n                Resources=PdfParser.PdfDict(\n                    ProcSet=[PdfParser.PdfName(\"PDF\"), PdfParser.PdfName(procset)],\n                    XObject=PdfParser.PdfDict(image=image_refs[pageNumber])),\n                MediaBox=[0, 0, int(width * 72.0 / resolution), int(height * 72.0 / resolution)],\n                Contents=contents_refs[pageNumber]\n                )\n\n            #\n            # page contents\n\n            page_contents = PdfParser.make_bytes(\n                \"q %d 0 0 %d 0 0 cm /image Do Q\\n\" % (\n                    int(width * 72.0 / resolution),\n                    int(height * 72.0 / resolution)))\n\n            existing_pdf.write_obj(contents_refs[pageNumber], stream=page_contents)\n\n            pageNumber += 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\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\nfrom . import Image, ImageFile, ImageSequence, PdfParser\nimport io\n\n__version__ = \"0.5\"\n\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\ndef _save(im, fp, filename, save_all=False):\n    resolution = im.encoderinfo.get(\"resolution\", 72.0)\n    is_appending = im.encoderinfo.get(\"append\", False)\n    title = im.encoderinfo.get(\"title\", None)\n    author = im.encoderinfo.get(\"author\", None)\n    subject = im.encoderinfo.get(\"subject\", None)\n    keywords = im.encoderinfo.get(\"keywords\", None)\n    creator = im.encoderinfo.get(\"creator\", None)\n    producer = im.encoderinfo.get(\"producer\", None)\n\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    if title:\n        existing_pdf.info.Title = title\n    if author:\n        existing_pdf.info.Author = author\n    if subject:\n        existing_pdf.info.Subject = subject\n    if keywords:\n        existing_pdf.info.Keywords = keywords\n    if creator:\n        existing_pdf.info.Creator = creator\n    if producer:\n        existing_pdf.info.Producer = producer\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(\"created by PIL PDF driver \" + __version__)\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    numberOfPages = 0\n    image_refs = []\n    page_refs = []\n    contents_refs = []\n    for im in ims:\n        im_numberOfPages = 1\n        if save_all:\n            try:\n                im_numberOfPages = im.n_frames\n            except AttributeError:\n                # Image format does not have n_frames. It is a single frame image\n                pass\n        numberOfPages += im_numberOfPages\n        for i in range(im_numberOfPages):\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    pageNumber = 0\n    for imSequence in ims:\n        im_pages = ImageSequence.Iterator(imSequence) if save_all else [imSequence]\n        for im in im_pages:\n            # FIXME: Should replace ASCIIHexDecode with RunLengthDecode (packbits)\n            # or LZWDecode (tiff/lzw compression).  Note that PDF 1.2 also supports\n            # Flatedecode (zip compression).\n\n            bits = 8\n            params = None\n\n            if im.mode == \"1\":\n                filter = \"ASCIIHexDecode\"\n                colorspace = PdfParser.PdfName(\"DeviceGray\")\n                procset = \"ImageB\"  # grayscale\n                bits = 1\n            elif im.mode == \"L\":\n                filter = \"DCTDecode\"\n                # params = \"<< /Predictor 15 /Columns %d >>\" % (width-2)\n                colorspace = PdfParser.PdfName(\"DeviceGray\")\n                procset = \"ImageB\"  # grayscale\n            elif im.mode == \"P\":\n                filter = \"ASCIIHexDecode\"\n                palette = im.im.getpalette(\"RGB\")\n                colorspace = [PdfParser.PdfName(\"Indexed\"), PdfParser.PdfName(\"DeviceRGB\"), 255, PdfParser.PdfBinary(palette)]\n                procset = \"ImageI\"  # indexed color\n            elif im.mode == \"RGB\":\n                filter = \"DCTDecode\"\n                colorspace = PdfParser.PdfName(\"DeviceRGB\")\n                procset = \"ImageC\"  # color images\n            elif im.mode == \"CMYK\":\n                filter = \"DCTDecode\"\n                colorspace = PdfParser.PdfName(\"DeviceCMYK\")\n                procset = \"ImageC\"  # color images\n            else:\n                raise ValueError(\"cannot save mode %s\" % im.mode)\n\n            #\n            # image\n\n            op = io.BytesIO()\n\n            if filter == \"ASCIIHexDecode\":\n                if bits == 1:\n                    # FIXME: the hex encoder doesn't support packed 1-bit\n                    # images; do things the hard way...\n                    data = im.tobytes(\"raw\", \"1\")\n                    im = Image.new(\"L\", (len(data), 1), None)\n                    im.putdata(data)\n                ImageFile._save(im, op, [(\"hex\", (0, 0)+im.size, 0, im.mode)])\n            elif filter == \"DCTDecode\":\n                Image.SAVE[\"JPEG\"](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                raise ValueError(\"unsupported PDF filter (%s)\" % filter)\n\n            #\n            # Get image characteristics\n\n            width, height = im.size\n\n            existing_pdf.write_obj(image_refs[pageNumber], stream=op.getvalue(),\n                Type=PdfParser.PdfName(\"XObject\"),\n                Subtype=PdfParser.PdfName(\"Image\"),\n                Width=width,  # * 72.0 / resolution,\n                Height=height,  # * 72.0 / resolution,\n                Filter=PdfParser.PdfName(filter),\n                BitsPerComponent=bits,\n                DecodeParams=params,\n                ColorSpace=colorspace)\n\n            #\n            # page\n\n            existing_pdf.write_page(page_refs[pageNumber],\n                Resources=PdfParser.PdfDict(\n                    ProcSet=[PdfParser.PdfName(\"PDF\"), PdfParser.PdfName(procset)],\n                    XObject=PdfParser.PdfDict(image=image_refs[pageNumber])),\n                MediaBox=[0, 0, int(width * 72.0 / resolution), int(height * 72.0 / resolution)],\n                Contents=contents_refs[pageNumber]\n                )\n\n            #\n            # page contents\n\n            page_contents = PdfParser.make_bytes(\n                \"q %d 0 0 %d 0 0 cm /image Do Q\\n\" % (\n                    int(width * 72.0 / resolution),\n                    int(height * 72.0 / resolution)))\n\n            existing_pdf.write_obj(contents_refs[pageNumber], stream=page_contents)\n\n            pageNumber += 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\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": "e8e0c4f3b",
                "new_commit_hash": "8538bcd49",
                "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": 113,
                            "length": 7
                        },
                        "new_range": {
                            "start": 113,
                            "length": 8
                        },
                        "section": "def _save(im, fp, filename, save_all=False):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "    pageNumber = 0",
                                "type": "context"
                            },
                            {
                                "content": "    for imSequence in ims:",
                                "type": "context"
                            },
                            {
                                "content": "        for im in ImageSequence.Iterator(imSequence):",
                                "type": "deleted"
                            },
                            {
                                "content": "        im_pages = ImageSequence.Iterator(imSequence) if save_all else [imSequence]",
                                "type": "added"
                            },
                            {
                                "content": "        for im in im_pages:",
                                "type": "added"
                            },
                            {
                                "content": "            # FIXME: Should replace ASCIIHexDecode with RunLengthDecode (packbits)",
                                "type": "context"
                            },
                            {
                                "content": "            # or LZWDecode (tiff/lzw compression).  Note that PDF 1.2 also supports",
                                "type": "context"
                            },
                            {
                                "content": "            # Flatedecode (zip compression).",
                                "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    resolution = im.encoderinfo.get(\"resolution\", 72.0)\n    is_appending = im.encoderinfo.get(\"append\", False)\n    title = im.encoderinfo.get(\"title\", None)\n    author = im.encoderinfo.get(\"author\", None)\n    subject = im.encoderinfo.get(\"subject\", None)\n    keywords = im.encoderinfo.get(\"keywords\", None)\n    creator = im.encoderinfo.get(\"creator\", None)\n    producer = im.encoderinfo.get(\"producer\", None)\n\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    if title:\n        existing_pdf.info.Title = title\n    if author:\n        existing_pdf.info.Author = author\n    if subject:\n        existing_pdf.info.Subject = subject\n    if keywords:\n        existing_pdf.info.Keywords = keywords\n    if creator:\n        existing_pdf.info.Creator = creator\n    if producer:\n        existing_pdf.info.Producer = producer\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(\"created by PIL PDF driver \" + __version__)\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    numberOfPages = 0\n    image_refs = []\n    page_refs = []\n    contents_refs = []\n    for im in ims:\n        im_numberOfPages = 1\n        if save_all:\n            try:\n                im_numberOfPages = im.n_frames\n            except AttributeError:\n                # Image format does not have n_frames. It is a single frame image\n                pass\n        numberOfPages += im_numberOfPages\n        for i in range(im_numberOfPages):\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    pageNumber = 0\n    for imSequence in ims:\n        for im in ImageSequence.Iterator(imSequence):\n            # FIXME: Should replace ASCIIHexDecode with RunLengthDecode (packbits)\n            # or LZWDecode (tiff/lzw compression).  Note that PDF 1.2 also supports\n            # Flatedecode (zip compression).\n\n            bits = 8\n            params = None\n\n            if im.mode == \"1\":\n                filter = \"ASCIIHexDecode\"\n                colorspace = PdfParser.PdfName(\"DeviceGray\")\n                procset = \"ImageB\"  # grayscale\n                bits = 1\n            elif im.mode == \"L\":\n                filter = \"DCTDecode\"\n                # params = \"<< /Predictor 15 /Columns %d >>\" % (width-2)\n                colorspace = PdfParser.PdfName(\"DeviceGray\")\n                procset = \"ImageB\"  # grayscale\n            elif im.mode == \"P\":\n                filter = \"ASCIIHexDecode\"\n                palette = im.im.getpalette(\"RGB\")\n                colorspace = [PdfParser.PdfName(\"Indexed\"), PdfParser.PdfName(\"DeviceRGB\"), 255, PdfParser.PdfBinary(palette)]\n                procset = \"ImageI\"  # indexed color\n            elif im.mode == \"RGB\":\n                filter = \"DCTDecode\"\n                colorspace = PdfParser.PdfName(\"DeviceRGB\")\n                procset = \"ImageC\"  # color images\n            elif im.mode == \"CMYK\":\n                filter = \"DCTDecode\"\n                colorspace = PdfParser.PdfName(\"DeviceCMYK\")\n                procset = \"ImageC\"  # color images\n            else:\n                raise ValueError(\"cannot save mode %s\" % im.mode)\n\n            #\n            # image\n\n            op = io.BytesIO()\n\n            if filter == \"ASCIIHexDecode\":\n                if bits == 1:\n                    # FIXME: the hex encoder doesn't support packed 1-bit\n                    # images; do things the hard way...\n                    data = im.tobytes(\"raw\", \"1\")\n                    im = Image.new(\"L\", (len(data), 1), None)\n                    im.putdata(data)\n                ImageFile._save(im, op, [(\"hex\", (0, 0)+im.size, 0, im.mode)])\n            elif filter == \"DCTDecode\":\n                Image.SAVE[\"JPEG\"](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                raise ValueError(\"unsupported PDF filter (%s)\" % filter)\n\n            #\n            # Get image characteristics\n\n            width, height = im.size\n\n            existing_pdf.write_obj(image_refs[pageNumber], stream=op.getvalue(),\n                Type=PdfParser.PdfName(\"XObject\"),\n                Subtype=PdfParser.PdfName(\"Image\"),\n                Width=width,  # * 72.0 / resolution,\n                Height=height,  # * 72.0 / resolution,\n                Filter=PdfParser.PdfName(filter),\n                BitsPerComponent=bits,\n                DecodeParams=params,\n                ColorSpace=colorspace)\n\n            #\n            # page\n\n            existing_pdf.write_page(page_refs[pageNumber],\n                Resources=PdfParser.PdfDict(\n                    ProcSet=[PdfParser.PdfName(\"PDF\"), PdfParser.PdfName(procset)],\n                    XObject=PdfParser.PdfDict(image=image_refs[pageNumber])),\n                MediaBox=[0, 0, int(width * 72.0 / resolution), int(height * 72.0 / resolution)],\n                Contents=contents_refs[pageNumber]\n                )\n\n            #\n            # page contents\n\n            page_contents = PdfParser.make_bytes(\n                \"q %d 0 0 %d 0 0 cm /image Do Q\\n\" % (\n                    int(width * 72.0 / resolution),\n                    int(height * 72.0 / resolution)))\n\n            existing_pdf.write_obj(contents_refs[pageNumber], stream=page_contents)\n\n            pageNumber += 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": 47,
                            "end_lineno": 215,
                            "parent": null
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                }
            ]
        }
    ],
    "old_commit_hash": "c222df2b56bbcd59a8089b9cc5085a19edd8dc70^",
    "new_commit_hash": "c222df2b56bbcd59a8089b9cc5085a19edd8dc70",
    "commit_message": "Merge pull request #3137 from radarhere/pdf\n\nFixed saving a multiframe image as a single frame PDF",
    "commit_date": "2018-07-01T22:18:48+03:00",
    "metadata": {}
}
{
    "repo_name": "pillow",
    "new_commit_hash": "c222df2b56bbcd59a8089b9cc5085a19edd8dc70",
    "test_file_codes": [
        "from helper import unittest, PillowTestCase, hopper\nfrom PIL import Image, PdfParser\nimport io\nimport os\nimport os.path\nimport tempfile\n\n\nclass TestFilePdf(PillowTestCase):\n\n    def helper_save_as_pdf(self, mode, **kwargs):\n        # Arrange\n        im = hopper(mode)\n        outfile = self.tempfile(\"temp_\" + mode + \".pdf\")\n\n        # Act\n        im.save(outfile, **kwargs)\n\n        # Assert\n        self.assertTrue(os.path.isfile(outfile))\n        self.assertGreater(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                self.assertGreater(len(pdf.pages), 1)\n            else:\n                self.assertGreater(len(pdf.pages), 0)\n\n        return outfile\n\n    def test_monochrome(self):\n        # Arrange\n        mode = \"1\"\n\n        # Act / Assert\n        self.helper_save_as_pdf(mode)\n\n    def test_greyscale(self):\n        # Arrange\n        mode = \"L\"\n\n        # Act / Assert\n        self.helper_save_as_pdf(mode)\n\n    def test_rgb(self):\n        # Arrange\n        mode = \"RGB\"\n\n        # Act / Assert\n        self.helper_save_as_pdf(mode)\n\n    def test_p_mode(self):\n        # Arrange\n        mode = \"P\"\n\n        # Act / Assert\n        self.helper_save_as_pdf(mode)\n\n    def test_cmyk_mode(self):\n        # Arrange\n        mode = \"CMYK\"\n\n        # Act / Assert\n        self.helper_save_as_pdf(mode)\n\n    def test_unsupported_mode(self):\n        im = hopper(\"LA\")\n        outfile = self.tempfile(\"temp_LA.pdf\")\n\n        self.assertRaises(ValueError, im.save, outfile)\n\n    def test_save_all(self):\n        # Single frame image\n        self.helper_save_as_pdf(\"RGB\", save_all=True)\n\n        # Multiframe image\n        im = Image.open(\"Tests/images/dispose_bgnd.gif\")\n\n        outfile = self.tempfile('temp.pdf')\n        im.save(outfile, save_all=True)\n\n        self.assertTrue(os.path.isfile(outfile))\n        self.assertGreater(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        self.assertTrue(os.path.isfile(outfile))\n        self.assertGreater(os.path.getsize(outfile), 0)\n\n        # Test appending using a generator\n        def imGenerator(ims):\n            for im in ims:\n                yield im\n        im.save(outfile, save_all=True, append_images=imGenerator(ims))\n\n        self.assertTrue(os.path.isfile(outfile))\n        self.assertGreater(os.path.getsize(outfile), 0)\n\n        # Append JPEG images\n        jpeg = Image.open(\"Tests/images/flower.jpg\")\n        jpeg.save(outfile, save_all=True, append_images=[jpeg.copy()])\n\n        self.assertTrue(os.path.isfile(outfile))\n        self.assertGreater(os.path.getsize(outfile), 0)\n\n    def test_multiframe_normal_save(self):\n        # Test saving a multiframe image without save_all\n        im = Image.open(\"Tests/images/dispose_bgnd.gif\")\n\n        outfile = self.tempfile('temp.pdf')\n        im.save(outfile)\n\n        self.assertTrue(os.path.isfile(outfile))\n        self.assertGreater(os.path.getsize(outfile), 0)\n\n    def test_pdf_open(self):\n        # fail on a buffer full of null bytes\n        self.assertRaises(PdfParser.PdfFormatError, PdfParser.PdfParser, buf=bytearray(65536))\n\n        # make an empty PDF object\n        with PdfParser.PdfParser() as empty_pdf:\n            self.assertEqual(len(empty_pdf.pages), 0)\n            self.assertEqual(len(empty_pdf.info), 0)\n            self.assertFalse(empty_pdf.should_close_buf)\n            self.assertFalse(empty_pdf.should_close_file)\n\n        # make a PDF file\n        pdf_filename = self.helper_save_as_pdf(\"RGB\")\n\n        # open the PDF file\n        with PdfParser.PdfParser(filename=pdf_filename) as hopper_pdf:\n            self.assertEqual(len(hopper_pdf.pages), 1)\n            self.assertTrue(hopper_pdf.should_close_buf)\n            self.assertTrue(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            self.assertEqual(len(hopper_pdf.pages), 1)\n            self.assertFalse(hopper_pdf.should_close_buf)\n            self.assertFalse(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                self.assertEqual(len(hopper_pdf.pages), 1)\n                self.assertTrue(hopper_pdf.should_close_buf)\n                self.assertFalse(hopper_pdf.should_close_file)\n\n    def test_pdf_append_fails_on_nonexistent_file(self):\n        im = hopper(\"RGB\")\n        temp_dir = tempfile.mkdtemp()\n        try:\n            self.assertRaises(IOError, im.save, os.path.join(temp_dir, \"nonexistent.pdf\"), append=True)\n        finally:\n            os.rmdir(temp_dir)\n\n    def check_pdf_pages_consistency(self, pdf):\n        pages_info = pdf.read_indirect(pdf.pages_ref)\n        self.assertNotIn(b\"Parent\", pages_info)\n        self.assertIn(b\"Kids\", 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                self.assertIn(b\"Parent\", page_info)\n                page_ref = page_info[b\"Parent\"]\n                if page_ref == pdf.pages_ref:\n                    break\n            self.assertEqual(pdf.pages_ref, page_info[b\"Parent\"])\n        self.assertEqual(kids_not_used, [])\n\n    def test_pdf_append(self):\n        # make a PDF file\n        pdf_filename = self.helper_save_as_pdf(\"RGB\", producer=\"PdfParser\")\n\n        # open it, check pages and info\n        with PdfParser.PdfParser(pdf_filename, mode=\"r+b\") as pdf:\n            self.assertEqual(len(pdf.pages), 1)\n            self.assertEqual(len(pdf.info), 1)\n            self.assertEqual(pdf.info.Producer, \"PdfParser\")\n            self.check_pdf_pages_consistency(pdf)\n\n            # append some info\n            pdf.info.Title = \"abc\"\n            pdf.info.Author = \"def\"\n            pdf.info.Subject = u\"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            self.assertEqual(len(pdf.pages), 1)\n            self.assertEqual(len(pdf.info), 6)\n            self.assertEqual(pdf.info.Title, \"abc\")\n            self.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            self.assertEqual(len(pdf.pages), 3)\n            self.assertEqual(len(pdf.info), 6)\n            self.assertEqual(PdfParser.decode_text(pdf.info[b\"Title\"]), \"abc\")\n            self.assertEqual(pdf.info.Title, \"abc\")\n            self.assertEqual(pdf.info.Producer, \"PdfParser\")\n            self.assertEqual(pdf.info.Keywords, \"qw)e\\\\r(ty\")\n            self.assertEqual(pdf.info.Subject, u\"ghi\\uABCD\")\n            self.check_pdf_pages_consistency(pdf)\n\n    def test_pdf_info(self):\n        # make a PDF file\n        pdf_filename = self.helper_save_as_pdf(\"RGB\", title=\"title\", author=\"author\", subject=\"subject\", keywords=\"keywords\", creator=\"creator\", producer=\"producer\")\n\n        # open it, check pages and info\n        with PdfParser.PdfParser(pdf_filename) as pdf:\n            self.assertEqual(len(pdf.info), 6)\n            self.assertEqual(pdf.info.Title, \"title\")\n            self.assertEqual(pdf.info.Author, \"author\")\n            self.assertEqual(pdf.info.Subject, \"subject\")\n            self.assertEqual(pdf.info.Keywords, \"keywords\")\n            self.assertEqual(pdf.info.Creator, \"creator\")\n            self.assertEqual(pdf.info.Producer, \"producer\")\n            self.check_pdf_pages_consistency(pdf)\n\n    def test_pdf_append_to_bytesio(self):\n        im = hopper(\"RGB\")\n        f = io.BytesIO()\n        im.save(f, format=\"PDF\")\n        initial_size = len(f.getvalue())\n        self.assertGreater(initial_size, 0)\n        im = hopper(\"P\")\n        f = io.BytesIO(f.getvalue())\n        im.save(f, format=\"PDF\", append=True)\n        self.assertGreater(len(f.getvalue()), initial_size)\n\n\nif __name__ == '__main__':\n    unittest.main()\n",
        "#!/usr/bin/env python\nimport unittest\nimport sys\nimport time\nimport traceback\nimport platform\nimport os\n\n\nclass PytestLikeResult(unittest.TestResult):\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        self.start_time = None\n        # Store (test, outcome, info) for each test:\n        #   outcome ∈ { \"passed\", \"failed\", \"error\", \"skipped\" }\n        #   info can hold the exception or skip reason, etc.\n        self.results = []\n\n    def startTestRun(self):\n        \"\"\"Called once before all tests.\"\"\"\n        self.start_time = time.time()\n        # Print a header similar to pytest\n        print(\"=\" * 29 + \" test session starts \" + \"=\" * 29)\n        # You can customize the platform/versions/paths as you like:\n        print(\n            f\"platform {platform.system().lower()} -- Python {platform.python_version()}\"\n        )\n        print(f\"rootdir: {os.path.abspath(os.curdir)}\")\n\n    def stopTestRun(self):\n        \"\"\"Called once after all tests are done.\"\"\"\n        elapsed = time.time() - self.start_time\n        print()  # blank line after final dot\n\n        # Summarize\n        ntests = len(self.results)\n        print(f\"collected {ntests} items\")\n\n        # Show details of failures/errors\n        failures = [r for r in self.results if r[1] == \"failed\"]\n        errors = [r for r in self.results if r[1] == \"error\"]\n\n        if failures:\n            print(\"\\n\" + \"=\" * 35 + \" FAILURES \" + \"=\" * 35)\n            for test, outcome, err_info in failures:\n                test = test.split(\"::\")\n                if len(test) == 3:\n                    test = f\"{test[1]}.{test[2]}\"\n                else:\n                    test = f\"{test[1]}\"\n                print(f\"__________ {test} __________\")\n                self._print_traceback(err_info)\n        if errors:\n            print(\"\\n\" + \"=\" * 35 + \" ERRORS \" + \"=\" * 37)\n            for test, outcome, err_info in errors:\n                test = test.split(\"::\")\n                if len(test) == 3:\n                    test = f\"{test[1]}.{test[2]}\"\n                else:\n                    test = f\"{test[1]}\"\n                print(f\"__________ {test} __________\")\n                self._print_traceback(err_info)\n\n        # Optional short summary lines for passes/fails/skips\n        print(\"\\n==================== short test summary info ====================\")\n        for test, outcome, info in self.results:\n            if outcome in (\"passed\", \"failed\", \"error\", \"skipped\"):\n                print(f\"{outcome.upper()} {test}\")\n\n        # Final one-line summary: “1 failed, 1 errors, 10 passed in 2.04s”\n        passed_count = sum(1 for r in self.results if r[1] == \"passed\")\n        failed_count = len(failures)\n        error_count = len(errors)\n        skipped_count = sum(1 for r in self.results if r[1] == \"skipped\")\n\n        summary_bits = []\n        if failed_count:\n            summary_bits.append(f\"{failed_count} failed\")\n        if error_count:\n            summary_bits.append(f\"{error_count} error{'s' if error_count != 1 else ''}\")\n        if passed_count:\n            summary_bits.append(f\"{passed_count} passed\")\n        if skipped_count:\n            summary_bits.append(f\"{skipped_count} skipped\")\n\n        summary_str = \", \".join(summary_bits) if summary_bits else \"no tests run\"\n        print(\n            f\"=================== {summary_str} in {elapsed:.2f}s ===================\"\n        )\n\n    def startTest(self, test):\n        \"\"\"Called right before each test method.\"\"\"\n        super().startTest(test)\n        # Print a dot or some indicator\n        print(\".\", end=\"\", flush=True)\n\n    def addSuccess(self, test):\n        super().addSuccess(test)\n        self.results.append((self._test_id(test), \"passed\", None))\n\n    def addFailure(self, test, err):\n        super().addFailure(test, err)\n        self.results.append((self._test_id(test), \"failed\", err))\n\n    def addError(self, test, err):\n        super().addError(test, err)\n        self.results.append((self._test_id(test), \"error\", err))\n\n    def addSkip(self, test, reason):\n        super().addSkip(test, reason)\n        self.results.append((self._test_id(test), \"skipped\", reason))\n\n    def _print_traceback(self, err_info):\n        \"\"\"Helper to print the traceback like pytest does.\"\"\"\n        if isinstance(err_info, tuple) and len(err_info) == 3:\n            exc_type, exc_value, tb = err_info\n            traceback.print_exception(exc_type, exc_value, tb, file=sys.stdout)\n        else:\n            print(str(err_info))\n\n    def _test_id(self, test):\n        try:\n            return f\"{test.__class__.__module__}::{test.__class__.__name__}::{test._testMethodName}\"\n        except AttributeError:\n            # Fallback for _ErrorHolder objects\n            return f\"{test.__class__.__module__}::{test.__class__.__name__}\"\n\n\nclass PytestLikeRunner(unittest.TextTestRunner):\n    \"\"\"A custom TextTestRunner that uses the PytestLikeResult.\"\"\"\n\n    resultclass = PytestLikeResult\n\n    def run(self, test):\n        result = self._makeResult()\n        # Overriding run to ensure we call startTestRun/stopTestRun\n        result.startTestRun()\n        test(result)\n        result.stopTestRun()\n        return result\n\n\ndef main():\n    loader = unittest.TestLoader()\n    suite = loader.discover(\"r2e_tests\")  # discover tests in r2e_tests/\n    runner = PytestLikeRunner(verbosity=0)\n    result = runner.run(suite)\n    # Exit with code 0 if all tests passed/skipped, 1 if there were fails/errors\n    sys.exit(not result.wasSuccessful())\n\n\nif __name__ == \"__main__\":\n    main()\n"
    ],
    "test_file_names": [
        "test_1.py",
        "unittest_custom_runner.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 13ms\nInstalled 12 packages in 174ms\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 902ms\nPrepared 1 package in 15.61s\nInstalled 1 package in 1ms\n + pillow==5.2.0.dev0 (from file:///home/gcpuser/buckets/local_repoeval_bucket/repos/pillow_c222df2b56bbcd59a8089b9cc5085a19edd8dc70)\n",
    "new_commit_res_code": 0,
    "new_commit_res_stdout": "============================= test session starts =============================\nplatform linux -- Python 3.9.21\nrootdir: /home/gcpuser/buckets/local_repoeval_bucket/repos/pillow_c222df2b56bbcd59a8089b9cc5085a19edd8dc70\n.............\ncollected 13 items\n\n==================== short test summary info ====================\nPASSED test_1::TestFilePdf::test_cmyk_mode\nPASSED test_1::TestFilePdf::test_greyscale\nPASSED test_1::TestFilePdf::test_monochrome\nPASSED test_1::TestFilePdf::test_multiframe_normal_save\nPASSED test_1::TestFilePdf::test_p_mode\nPASSED test_1::TestFilePdf::test_pdf_append\nPASSED test_1::TestFilePdf::test_pdf_append_fails_on_nonexistent_file\nPASSED test_1::TestFilePdf::test_pdf_append_to_bytesio\nPASSED test_1::TestFilePdf::test_pdf_info\nPASSED test_1::TestFilePdf::test_pdf_open\nPASSED test_1::TestFilePdf::test_rgb\nPASSED test_1::TestFilePdf::test_save_all\nPASSED test_1::TestFilePdf::test_unsupported_mode\n=================== 13 passed in 0.65s ===================\n",
    "new_commit_res_stderr": "",
    "old_commit_res_code": 1,
    "old_commit_res_stdout": "============================= test session starts =============================\nplatform linux -- Python 3.9.21\nrootdir: /home/gcpuser/buckets/local_repoeval_bucket/repos/pillow_c222df2b56bbcd59a8089b9cc5085a19edd8dc70\n.....=== orphaned temp file: /tmp/temp_m1fy972_P.pdf\n.=== orphaned temp file: /tmp/tempsn3x4dkp_RGB.pdf\n...=== orphaned temp file: /tmp/temp1atk303v_RGB.pdf\n.=== orphaned temp file: /tmp/tempof0w82ij_RGB.pdf\n.=== orphaned temp file: /tmp/tempptuc8lfh_RGB.pdf\n.=== orphaned temp file: /tmp/tempunwxhq8d.pdf\n=== orphaned temp file: /tmp/temp36q55emz_RGB.pdf\n.=== orphaned temp file: /tmp/tempdkbbo1on_LA.pdf\n\ncollected 13 items\n\n=================================== ERRORS =====================================\n__________ TestFilePdf.test_multiframe_normal_save __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/pillow_c222df2b56bbcd59a8089b9cc5085a19edd8dc70/r2e_tests/test_1.py\", line 112, in test_multiframe_normal_save\n    im.save(outfile)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/pillow_c222df2b56bbcd59a8089b9cc5085a19edd8dc70/src/PIL/Image.py\", line 1950, in save\n    save_handler(self, fp, filename)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/pillow_c222df2b56bbcd59a8089b9cc5085a19edd8dc70/src/PIL/PdfImagePlugin.py\", line 177, in _save\n    existing_pdf.write_obj(image_refs[pageNumber], stream=op.getvalue(),\nIndexError: list index out of range\n\n==================== short test summary info ====================\nPASSED test_1::TestFilePdf::test_cmyk_mode\nPASSED test_1::TestFilePdf::test_greyscale\nPASSED test_1::TestFilePdf::test_monochrome\nERROR test_1::TestFilePdf::test_multiframe_normal_save\nPASSED test_1::TestFilePdf::test_p_mode\nPASSED test_1::TestFilePdf::test_pdf_append\nPASSED test_1::TestFilePdf::test_pdf_append_fails_on_nonexistent_file\nPASSED test_1::TestFilePdf::test_pdf_append_to_bytesio\nPASSED test_1::TestFilePdf::test_pdf_info\nPASSED test_1::TestFilePdf::test_pdf_open\nPASSED test_1::TestFilePdf::test_rgb\nPASSED test_1::TestFilePdf::test_save_all\nPASSED test_1::TestFilePdf::test_unsupported_mode\n=================== 1 error, 12 passed in 0.73s ===================\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:** Saving a multiframe image as a single frame PDF causes IndexError

**Description:**

When attempting to save a multiframe image as a single-frame PDF, an `IndexError` is raised, preventing the PDF from being created successfully.

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

im = Image.open("Tests/images/dispose_bgnd.gif")
outfile = "temp.pdf"
im.save(outfile)
```

**Expected Behavior:**

The multiframe image should be saved as a single-frame PDF without any errors, resulting in a valid PDF file.

**Actual Behavior:**

An `IndexError: list index out of range` occurs during the save process, causing the operation to fail.

[/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).
##

from . import Image, ImageFile, ImageSequence, PdfParser
import io

__version__ = "0.5"


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

# 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 _save(im, fp, filename, save_all=False):
    resolution = im.encoderinfo.get("resolution", 72.0)
    is_appending = im.encoderinfo.get("append", False)
    title = im.encoderinfo.get("title", None)
    author = im.encoderinfo.get("author", None)
    subject = im.encoderinfo.get("subject", None)
    keywords = im.encoderinfo.get("keywords", None)
    creator = im.encoderinfo.get("creator", None)
    producer = im.encoderinfo.get("producer", None)

    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")

    if title:
        existing_pdf.info.Title = title
    if author:
        existing_pdf.info.Author = author
    if subject:
        existing_pdf.info.Subject = subject
    if keywords:
        existing_pdf.info.Keywords = keywords
    if creator:
        existing_pdf.info.Creator = creator
    if producer:
        existing_pdf.info.Producer = producer

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

    existing_pdf.start_writing()
    existing_pdf.write_header()
    existing_pdf.write_comment("created by PIL PDF driver " + __version__)

    #
    # 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)
    numberOfPages = 0
    image_refs = []
    page_refs = []
    contents_refs = []
    for im in ims:
        im_numberOfPages = 1
        if save_all:
            try:
                im_numberOfPages = im.n_frames
            except AttributeError:
                # Image format does not have n_frames. It is a single frame image
                pass
        numberOfPages += im_numberOfPages
        for i in range(im_numberOfPages):
            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()

    pageNumber = 0
    for imSequence in ims:
        for im in ImageSequence.Iterator(imSequence):
            # FIXME: Should replace ASCIIHexDecode with RunLengthDecode (packbits)
            # or LZWDecode (tiff/lzw compression).  Note that PDF 1.2 also supports
            # Flatedecode (zip compression).

            bits = 8
            params = None

            if im.mode == "1":
                filter = "ASCIIHexDecode"
                colorspace = PdfParser.PdfName("DeviceGray")
                procset = "ImageB"  # grayscale
                bits = 1
            elif im.mode == "L":
                filter = "DCTDecode"
                # params = "<< /Predictor 15 /Columns %d >>" % (width-2)
                colorspace = PdfParser.PdfName("DeviceGray")
                procset = "ImageB"  # grayscale
            elif im.mode == "P":
                filter = "ASCIIHexDecode"
                palette = im.im.getpalette("RGB")
                colorspace = [PdfParser.PdfName("Indexed"), PdfParser.PdfName("DeviceRGB"), 255, PdfParser.PdfBinary(palette)]
                procset = "ImageI"  # indexed color
            elif im.mode == "RGB":
                filter = "DCTDecode"
                colorspace = PdfParser.PdfName("DeviceRGB")
                procset = "ImageC"  # color images
            elif im.mode == "CMYK":
                filter = "DCTDecode"
                colorspace = PdfParser.PdfName("DeviceCMYK")
                procset = "ImageC"  # color images
            else:
                raise ValueError("cannot save mode %s" % im.mode)

            #
            # image

            op = io.BytesIO()

            if filter == "ASCIIHexDecode":
                if bits == 1:
                    # FIXME: the hex encoder doesn't support packed 1-bit
                    # images; do things the hard way...
                    data = im.tobytes("raw", "1")
                    im = Image.new("L", (len(data), 1), None)
                    im.putdata(data)
                ImageFile._save(im, op, [("hex", (0, 0)+im.size, 0, im.mode)])
            elif filter == "DCTDecode":
                Image.SAVE["JPEG"](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:
                raise ValueError("unsupported PDF filter (%s)" % filter)

            #
            # Get image characteristics

            width, height = im.size

            existing_pdf.write_obj(image_refs[pageNumber], stream=op.getvalue(),
                Type=PdfParser.PdfName("XObject"),
                Subtype=PdfParser.PdfName("Image"),
                Width=width,  # * 72.0 / resolution,
                Height=height,  # * 72.0 / resolution,
                Filter=PdfParser.PdfName(filter),
                BitsPerComponent=bits,
                DecodeParams=params,
                ColorSpace=colorspace)

            #
            # page

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

            #
            # page contents

            page_contents = PdfParser.make_bytes(
                "q %d 0 0 %d 0 0 cm /image Do Q\n" % (
                    int(width * 72.0 / resolution),
                    int(height * 72.0 / resolution)))

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

            pageNumber += 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:** Saving a multiframe image as a single frame PDF causes IndexError

**Description:**

When attempting to save a multiframe image as a single-frame PDF, an `IndexError` is raised, preventing the PDF from being created successfully.

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

im = Image.open("Tests/images/dispose_bgnd.gif")
outfile = "temp.pdf"
im.save(outfile)
```

**Expected Behavior:**

The multiframe image should be saved as a single-frame PDF without any errors, resulting in a valid PDF file.

**Actual Behavior:**

An `IndexError: list index out of range` occurs during the save process, causing the operation to fail.

[/ISSUE]
{
    "TestFilePdf.test_cmyk_mode": "PASSED",
    "TestFilePdf.test_greyscale": "PASSED",
    "TestFilePdf.test_monochrome": "PASSED",
    "TestFilePdf.test_multiframe_normal_save": "PASSED",
    "TestFilePdf.test_p_mode": "PASSED",
    "TestFilePdf.test_pdf_append": "PASSED",
    "TestFilePdf.test_pdf_append_fails_on_nonexistent_file": "PASSED",
    "TestFilePdf.test_pdf_append_to_bytesio": "PASSED",
    "TestFilePdf.test_pdf_info": "PASSED",
    "TestFilePdf.test_pdf_open": "PASSED",
    "TestFilePdf.test_rgb": "PASSED",
    "TestFilePdf.test_save_all": "PASSED",
    "TestFilePdf.test_unsupported_mode": "PASSED"
}
diff --git a/src/PIL/PdfImagePlugin.py b/src/PIL/PdfImagePlugin.py
index e8e0c4f3b..8538bcd49 100644
--- a/src/PIL/PdfImagePlugin.py
+++ b/src/PIL/PdfImagePlugin.py
@@ -113,7 +113,8 @@ def _save(im, fp, filename, save_all=False):
 
     pageNumber = 0
     for imSequence in ims:
-        for im in ImageSequence.Iterator(imSequence):
+        im_pages = ImageSequence.Iterator(imSequence) if save_all else [imSequence]
+        for im in im_pages:
             # FIXME: Should replace ASCIIHexDecode with RunLengthDecode (packbits)
             # or LZWDecode (tiff/lzw compression).  Note that PDF 1.2 also supports
             # Flatedecode (zip compression).
 

{"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\nfrom . import Image, ImageFile, ImageSequence, PdfParser\nimport io\n\n__version__ = \"0.5\"\n\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\ndef _save(im, fp, filename, save_all=False):\n    resolution = im.encoderinfo.get(\"resolution\", 72.0)\n    is_appending = im.encoderinfo.get(\"append\", False)\n    title = im.encoderinfo.get(\"title\", None)\n    author = im.encoderinfo.get(\"author\", None)\n    subject = im.encoderinfo.get(\"subject\", None)\n    keywords = im.encoderinfo.get(\"keywords\", None)\n    creator = im.encoderinfo.get(\"creator\", None)\n    producer = im.encoderinfo.get(\"producer\", None)\n\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    if title:\n        existing_pdf.info.Title = title\n    if author:\n        existing_pdf.info.Author = author\n    if subject:\n        existing_pdf.info.Subject = subject\n    if keywords:\n        existing_pdf.info.Keywords = keywords\n    if creator:\n        existing_pdf.info.Creator = creator\n    if producer:\n        existing_pdf.info.Producer = producer\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(\"created by PIL PDF driver \" + __version__)\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    numberOfPages = 0\n    image_refs = []\n    page_refs = []\n    contents_refs = []\n    for im in ims:\n        im_numberOfPages = 1\n        if save_all:\n            try:\n                im_numberOfPages = im.n_frames\n            except AttributeError:\n                # Image format does not have n_frames. It is a single frame image\n                pass\n        numberOfPages += im_numberOfPages\n        for i in range(im_numberOfPages):\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    pageNumber = 0\n    for imSequence in ims:\n        for im in ImageSequence.Iterator(imSequence):\n            # FIXME: Should replace ASCIIHexDecode with RunLengthDecode (packbits)\n            # or LZWDecode (tiff/lzw compression).  Note that PDF 1.2 also supports\n            # Flatedecode (zip compression).\n\n            bits = 8\n            params = None\n\n            if im.mode == \"1\":\n                filter = \"ASCIIHexDecode\"\n                colorspace = PdfParser.PdfName(\"DeviceGray\")\n                procset = \"ImageB\"  # grayscale\n                bits = 1\n            elif im.mode == \"L\":\n                filter = \"DCTDecode\"\n                # params = \"<< /Predictor 15 /Columns %d >>\" % (width-2)\n                colorspace = PdfParser.PdfName(\"DeviceGray\")\n                procset = \"ImageB\"  # grayscale\n            elif im.mode == \"P\":\n                filter = \"ASCIIHexDecode\"\n                palette = im.im.getpalette(\"RGB\")\n                colorspace = [PdfParser.PdfName(\"Indexed\"), PdfParser.PdfName(\"DeviceRGB\"), 255, PdfParser.PdfBinary(palette)]\n                procset = \"ImageI\"  # indexed color\n            elif im.mode == \"RGB\":\n                filter = \"DCTDecode\"\n                colorspace = PdfParser.PdfName(\"DeviceRGB\")\n                procset = \"ImageC\"  # color images\n            elif im.mode == \"CMYK\":\n                filter = \"DCTDecode\"\n                colorspace = PdfParser.PdfName(\"DeviceCMYK\")\n                procset = \"ImageC\"  # color images\n            else:\n                raise ValueError(\"cannot save mode %s\" % im.mode)\n\n            #\n            # image\n\n            op = io.BytesIO()\n\n            if filter == \"ASCIIHexDecode\":\n                if bits == 1:\n                    # FIXME: the hex encoder doesn't support packed 1-bit\n                    # images; do things the hard way...\n                    data = im.tobytes(\"raw\", \"1\")\n                    im = Image.new(\"L\", (len(data), 1), None)\n                    im.putdata(data)\n                ImageFile._save(im, op, [(\"hex\", (0, 0)+im.size, 0, im.mode)])\n            elif filter == \"DCTDecode\":\n                Image.SAVE[\"JPEG\"](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                raise ValueError(\"unsupported PDF filter (%s)\" % filter)\n\n            #\n            # Get image characteristics\n\n            width, height = im.size\n\n            existing_pdf.write_obj(image_refs[pageNumber], stream=op.getvalue(),\n                Type=PdfParser.PdfName(\"XObject\"),\n                Subtype=PdfParser.PdfName(\"Image\"),\n                Width=width,  # * 72.0 / resolution,\n                Height=height,  # * 72.0 / resolution,\n                Filter=PdfParser.PdfName(filter),\n                BitsPerComponent=bits,\n                DecodeParams=params,\n                ColorSpace=colorspace)\n\n            #\n            # page\n\n            existing_pdf.write_page(page_refs[pageNumber],\n                Resources=PdfParser.PdfDict(\n                    ProcSet=[PdfParser.PdfName(\"PDF\"), PdfParser.PdfName(procset)],\n                    XObject=PdfParser.PdfDict(image=image_refs[pageNumber])),\n                MediaBox=[0, 0, int(width * 72.0 / resolution), int(height * 72.0 / resolution)],\n                Contents=contents_refs[pageNumber]\n                )\n\n            #\n            # page contents\n\n            page_contents = PdfParser.make_bytes(\n                \"q %d 0 0 %d 0 0 cm /image Do Q\\n\" % (\n                    int(width * 72.0 / resolution),\n                    int(height * 72.0 / resolution)))\n\n            existing_pdf.write_obj(contents_refs[pageNumber], stream=page_contents)\n\n            pageNumber += 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\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:** Saving a multiframe image as a single frame PDF causes IndexError

**Description:**

When attempting to save a multiframe image as a single-frame PDF, an `IndexError` is raised, preventing the PDF from being created successfully.

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

im = Image.open("Tests/images/dispose_bgnd.gif")
outfile = "temp.pdf"
im.save(outfile)
```

**Expected Behavior:**

The multiframe image should be saved as a single-frame PDF without any errors, resulting in a valid PDF file.

**Actual Behavior:**

An `IndexError: list index out of range` occurs during the save process, causing the operation to fail.

[/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).
##

from . import Image, ImageFile, ImageSequence, PdfParser
import io

__version__ = "0.5"


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

# 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 _save(im, fp, filename, save_all=False):
    resolution = im.encoderinfo.get("resolution", 72.0)
    is_appending = im.encoderinfo.get("append", False)
    title = im.encoderinfo.get("title", None)
    author = im.encoderinfo.get("author", None)
    subject = im.encoderinfo.get("subject", None)
    keywords = im.encoderinfo.get("keywords", None)
    creator = im.encoderinfo.get("creator", None)
    producer = im.encoderinfo.get("producer", None)

    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")

    if title:
        existing_pdf.info.Title = title
    if author:
        existing_pdf.info.Author = author
    if subject:
        existing_pdf.info.Subject = subject
    if keywords:
        existing_pdf.info.Keywords = keywords
    if creator:
        existing_pdf.info.Creator = creator
    if producer:
        existing_pdf.info.Producer = producer

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

    existing_pdf.start_writing()
    existing_pdf.write_header()
    existing_pdf.write_comment("created by PIL PDF driver " + __version__)

    #
    # 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)
    numberOfPages = 0
    image_refs = []
    page_refs = []
    contents_refs = []
    for im in ims:
        im_numberOfPages = 1
        if save_all:
            try:
                im_numberOfPages = im.n_frames
            except AttributeError:
                # Image format does not have n_frames. It is a single frame image
                pass
        numberOfPages += im_numberOfPages
        for i in range(im_numberOfPages):
            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()

    pageNumber = 0
    for imSequence in ims:
        for im in ImageSequence.Iterator(imSequence):
            # FIXME: Should replace ASCIIHexDecode with RunLengthDecode (packbits)
            # or LZWDecode (tiff/lzw compression).  Note that PDF 1.2 also supports
            # Flatedecode (zip compression).

            bits = 8
            params = None

            if im.mode == "1":
                filter = "ASCIIHexDecode"
                colorspace = PdfParser.PdfName("DeviceGray")
                procset = "ImageB"  # grayscale
                bits = 1
            elif im.mode == "L":
                filter = "DCTDecode"
                # params = "<< /Predictor 15 /Columns %d >>" % (width-2)
                colorspace = PdfParser.PdfName("DeviceGray")
                procset = "ImageB"  # grayscale
            elif im.mode == "P":
                filter = "ASCIIHexDecode"
                palette = im.im.getpalette("RGB")
                colorspace = [PdfParser.PdfName("Indexed"), PdfParser.PdfName("DeviceRGB"), 255, PdfParser.PdfBinary(palette)]
                procset = "ImageI"  # indexed color
            elif im.mode == "RGB":
                filter = "DCTDecode"
                colorspace = PdfParser.PdfName("DeviceRGB")
                procset = "ImageC"  # color images
            elif im.mode == "CMYK":
                filter = "DCTDecode"
                colorspace = PdfParser.PdfName("DeviceCMYK")
                procset = "ImageC"  # color images
            else:
                raise ValueError("cannot save mode %s" % im.mode)

            #
            # image

            op = io.BytesIO()

            if filter == "ASCIIHexDecode":
                if bits == 1:
                    # FIXME: the hex encoder doesn't support packed 1-bit
                    # images; do things the hard way...
                    data = im.tobytes("raw", "1")
                    im = Image.new("L", (len(data), 1), None)
                    im.putdata(data)
                ImageFile._save(im, op, [("hex", (0, 0)+im.size, 0, im.mode)])
            elif filter == "DCTDecode":
                Image.SAVE["JPEG"](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:
                raise ValueError("unsupported PDF filter (%s)" % filter)

            #
            # Get image characteristics

            width, height = im.size

            existing_pdf.write_obj(image_refs[pageNumber], stream=op.getvalue(),
                Type=PdfParser.PdfName("XObject"),
                Subtype=PdfParser.PdfName("Image"),
                Width=width,  # * 72.0 / resolution,
                Height=height,  # * 72.0 / resolution,
                Filter=PdfParser.PdfName(filter),
                BitsPerComponent=bits,
                DecodeParams=params,
                ColorSpace=colorspace)

            #
            # page

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

            #
            # page contents

            page_contents = PdfParser.make_bytes(
                "q %d 0 0 %d 0 0 cm /image Do Q\n" % (
                    int(width * 72.0 / resolution),
                    int(height * 72.0 / resolution)))

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

            pageNumber += 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