Skip to content

Commit

Permalink
upload v1.18.8.
Browse files Browse the repository at this point in the history
  • Loading branch information
JorjMcKie committed Feb 4, 2021
1 parent 4cc565c commit 444b5eb
Show file tree
Hide file tree
Showing 9 changed files with 103 additions and 62 deletions.
6 changes: 3 additions & 3 deletions PKG-INFO
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: PyMuPDF
Version: 1.18.7
Version: 1.18.8
Author: Jorj McKie
Author-email: [email protected]
Maintainer: Jorj McKie
Expand All @@ -9,7 +9,7 @@ Home-page: https://github.com/pymupdf/PyMuPDF
Download-url: https://github.com/pymupdf/PyMuPDF
Summary: PyMuPDF is a Python binding for the PDF rendering library MuPDF
Description:
Release date: January 31, 2021
Release date: February 3, 2021

Authors
=======
Expand All @@ -20,7 +20,7 @@ Description:
Introduction
============

This is **version 1.18.7 of PyMuPDF**, a Python binding for `MuPDF <http://mupdf.com/>`_ - "a lightweight PDF and XPS viewer".
This is **version 1.18.8 of PyMuPDF**, a Python binding for `MuPDF <http://mupdf.com/>`_ - "a lightweight PDF and XPS viewer".

MuPDF can access files in PDF, XPS, OpenXPS, epub, comic and fiction book formats, and it is known for both, its top performance and high rendering quality.

Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# PyMuPDF 1.18.7
# PyMuPDF 1.18.8

![logo](https://github.com/pymupdf/PyMuPDF/blob/master/demo/pymupdf.jpg)

Release date: January 31, 2021
Release date: February 3, 2021

**Travis-CI:** [![Build Status](https://travis-ci.org/JorjMcKie/py-mupdf.svg?branch=master)](https://travis-ci.org/JorjMcKie/py-mupdf)

Expand All @@ -15,7 +15,7 @@ On **[PyPI](https://pypi.org/project/PyMuPDF)** since August 2016: [![Downloads]

# Introduction

This is **version 1.18.7 of PyMuPDF**, a Python binding with support for [MuPDF 1.18.*](http://mupdf.com/) - "a lightweight PDF, XPS, and E-book viewer".
This is **version 1.18.8 of PyMuPDF**, a Python binding with support for [MuPDF 1.18.*](http://mupdf.com/) - "a lightweight PDF, XPS, and E-book viewer".

MuPDF can access files in PDF, XPS, OpenXPS, CBZ, EPUB and FB2 (e-books) formats, and it is known for its top performance and high rendering quality.

Expand Down
9 changes: 9 additions & 0 deletions docs/changes.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
Change Logs
===============

Changes in Version 1.18.8
-------------------------

This is a bug fix version only. We are publishing early because of the potentially widely used functions.

* **Fixed** issue `#881 <https://github.com/pymupdf/PyMuPDF/issues/881>`_. Fixed a memory leak in :meth:`Page.insert_image` when inserting images from files or memory.
* **Fixed** issue `#878 <https://github.com/pymupdf/PyMuPDF/issues/878>`_. ``pathlib.Path`` objects should now correctly handle file path hierarchies.


Changes in Version 1.18.7
-------------------------

Expand Down
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
# built documents.
#
# The full version, including alpha/beta/rc tags.
release = "1.18.7"
release = "1.18.8"

# The short X.Y version
version = release
Expand Down
2 changes: 1 addition & 1 deletion docs/version.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Covered Version
--------------------

This documentation covers PyMuPDF v1.18.7 features as of **2021-01-31 00:00:01**.
This documentation covers PyMuPDF v1.18.8 features as of **2021-02-03 19:56:11**.

.. note:: The major and minor versions of **PyMuPDF** and **MuPDF** will always be the same. Only the third qualifier (patch level) may deviate from that of MuPDF.
74 changes: 53 additions & 21 deletions fitz/fitz.i
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,8 @@ struct Document
"""
if not filename or type(filename) is str:
pass
elif hasattr(filename, "absolute"):
filename = str(filename)
elif hasattr(filename, "name"):
filename = filename.name
else:
Expand Down Expand Up @@ -691,9 +693,10 @@ struct Document
_extend_toc_items(PyObject *items)
{
pdf_document *pdf = pdf_specifics(gctx, (fz_document *)$self);
pdf_obj *bm, *col;
pdf_obj *bm, *col, *obj;
int count, flags;
PyObject *item=NULL, *itemdict=NULL, *xrefs, *bold, *italic, *collapse;
PyObject *item=NULL, *itemdict=NULL, *xrefs, *bold, *italic, *collapse, *zoom;
zoom = PyUnicode_FromString("zoom");
bold = PyUnicode_FromString("bold");
italic = PyUnicode_FromString("italic");
collapse = PyUnicode_FromString("collapse");
Expand All @@ -704,7 +707,7 @@ struct Document
if (!olroot) goto finished;
pdf_obj *first = pdf_dict_get(gctx, olroot, PDF_NAME(First));
if (!first) goto finished;
xrefs = PyList_New(0);
xrefs = PyList_New(0); // pre-allocate an empty list
xrefs = JM_outline_xrefs(gctx, first, xrefs);
Py_ssize_t i, n = PySequence_Size(xrefs);
if (!n) goto finished;
Expand Down Expand Up @@ -743,6 +746,15 @@ struct Document
PyTuple_SET_ITEM(color, 2, Py_BuildValue("f", pdf_to_real(gctx, pdf_array_get(gctx, col, 2))));
DICT_SETITEM_DROP(itemdict, dictkey_color, color);
}
float z=0;
obj = pdf_dict_get(gctx, bm, PDF_NAME(Dest));
if (!obj || !pdf_is_array(gctx, obj)) {
obj = pdf_dict_getl(gctx, bm, PDF_NAME(A), PDF_NAME(D), NULL);
}
if (pdf_is_array(gctx, obj) && pdf_array_len(gctx, obj) == 5) {
z = pdf_to_real(gctx, pdf_array_get(gctx, obj, 4));
}
DICT_SETITEM_DROP(itemdict, zoom, Py_BuildValue("f", z));
PyList_SetItem(item, 3, itemdict);
PyList_SetItem(items, i, item);
pdf_drop_obj(gctx, bm);
Expand All @@ -755,6 +767,7 @@ struct Document
Py_CLEAR(bold);
Py_CLEAR(italic);
Py_CLEAR(collapse);
Py_CLEAR(zoom);
pdf_drop_obj(gctx, bm);
PyErr_Clear();
}
Expand Down Expand Up @@ -1749,8 +1762,10 @@ struct Document
pass
elif hasattr(filename, "open"): # assume: pathlib.Path
filename = str(filename)
elif not hasattr(filename, "seek"): # assume: file pointer
raise ValueError("filename must be str, Path or file pointer")
elif hasattr(filename, "name"): # assume: file object
filename = filename.name
elif not hasattr(filename, "seek"): # assume file object
raise ValueError("filename must be str, Path or file object")
if filename == self.name and not incremental:
raise ValueError("save to original must be incremental")
if self.page_count < 1:
Expand Down Expand Up @@ -3876,7 +3891,7 @@ if basestate:
raise ValueError("bad page number(s)")
# remove TOC bookmarks pointing to deleted page
old_toc = self.getToC()
old_toc = self.get_toc()
for i, item in enumerate(old_toc):
if item[2] == pno + 1:
self.del_toc_item(i)
Expand Down Expand Up @@ -3904,7 +3919,7 @@ if basestate:
if not f <= t < page_count:
raise ValueError("bad page number(s)")
old_toc = self.getToC()
old_toc = self.get_toc()
for i, item in enumerate(old_toc):
if f + 1 <= item[2] <= t + 1:
self.del_toc_item(i)
Expand Down Expand Up @@ -5509,9 +5524,9 @@ def get_oc_items(self) -> list:
fz_rect cropbox = fz_empty_rect;
fz_rect r = JM_rect_from_py(rect);
cropbox.x0 = r.x0;
cropbox.y0 = mediabox.y1 - r.y1;
cropbox.x1 = r.x1;
cropbox.y1 = mediabox.y1 - r.y0;
cropbox.y0 = mediabox.y1 - r.y1 + mediabox.y0;
cropbox.y1 = mediabox.y1 - r.y0 + mediabox.y0;
pdf_dict_put_drop(gctx, page->obj, PDF_NAME(CropBox),
pdf_new_rect(gctx, page->doc, cropbox));
}
Expand Down Expand Up @@ -5920,7 +5935,7 @@ if not sanitize and not self.is_wrapped:
// insert an image
//----------------------------------------------------------------
FITZEXCEPTION(_insertImage, !result)
PyObject *_insertImage(const char *filename=NULL, struct Pixmap *pixmap=NULL, PyObject *stream=NULL, PyObject *imask=NULL, int overlay=1, int oc=0, int xref = 0, PyObject *matrix=NULL,
PyObject *_insertImage(const char *filename=NULL, struct Pixmap *pixmap=NULL, PyObject *stream=NULL, PyObject *imask=NULL, int overlay=1, int oc=0, int xref=0, int alpha=0, PyObject *matrix=NULL,
const char *_imgname=NULL, PyObject *_imgpointer=NULL)
{
pdf_page *page = pdf_page_from_fz_page(gctx, (fz_page *) $self);
Expand All @@ -5944,8 +5959,7 @@ if not sanitize and not self.is_wrapped:
//-------------------------------------------------------------
// create the image
//-------------------------------------------------------------
if (filename || EXISTS(stream) || EXISTS(_imgpointer))
{
if (filename || EXISTS(stream) || EXISTS(_imgpointer)) {
if (filename) {
image = fz_new_image_from_file(gctx, filename);
} else if (EXISTS(stream)) {
Expand All @@ -5968,11 +5982,11 @@ if not sanitize and not self.is_wrapped:
fz_drop_image(gctx, image);
image = zimg;
zimg = NULL;
} else {
pix = fz_get_pixmap_from_image(gctx, image, NULL, NULL, 0, 0);
pix->xres = xres;
pix->yres = yres;
if (pix->alpha == 1) { // have alpha: create an SMask
} else if (alpha == 1) {
// have alpha: create an SMask
pix = fz_get_pixmap_from_image(gctx, image, NULL, NULL, 0, 0);
pix->xres = xres;
pix->yres = yres;
pm = fz_convert_pixmap(gctx, pix, NULL, NULL, NULL, fz_default_color_params, 1);
pm->alpha = 0;
pm->colorspace = fz_keep_colorspace(gctx, fz_device_gray(gctx));
Expand All @@ -5981,10 +5995,6 @@ if not sanitize and not self.is_wrapped:
fz_drop_image(gctx, image);
image = zimg;
zimg = NULL;
} else {
fz_drop_pixmap(gctx, pix);
pix = NULL;
}
}
} else { // pixmap specified
fz_pixmap *arg_pix = (fz_pixmap *) pixmap;
Expand Down Expand Up @@ -7212,6 +7222,28 @@ Use pillowWrite to reflect this in output image."""%}
return rc;
}
//-----------------------------------------------------------------
// check if monochrome
//-----------------------------------------------------------------
%pythoncode %{@property%}
%pythonprepend is_monochrome %{"""Check if pixmap is monochrome."""%}
PyObject *is_monochrome()
{
return JM_BOOL(fz_is_pixmap_monochrome(gctx, (fz_pixmap *) $self));
}
//-----------------------------------------------------------------
// MD5 digest of pixmap
//-----------------------------------------------------------------
%pythoncode %{@property%}
%pythonprepend digest %{"""MD5 digest of pixmap (bytes)."""%}
PyObject *digest()
{
unsigned char digest[16];
fz_md5_pixmap(gctx, (fz_pixmap *) $self, digest);
return Py_BuildValue("y", digest);
}
//-----------------------------------------------------------------
// get length of one image row
//-----------------------------------------------------------------
Expand Down
56 changes: 28 additions & 28 deletions fitz/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ def insertImage(*args, **kwargs) -> None:
overlay = bool(kwargs.get("overlay", True))

def calc_hash(stream):
m = hashlib.sha1()
m = hashlib.md5()
m.update(stream)
return m.digest()

Expand Down Expand Up @@ -336,31 +336,30 @@ def calc_matrix(fw, fh, tr, rotate=0):
# to the actual C-level function (_imgpointer), and set all other
# parameters to None.
# -------------------------------------------------------------------------
if keep_proportion is True: # for this we need the image dimension
if pixmap: # this is the easy case
w = pixmap.width
h = pixmap.height
digest = calc_hash(pixmap.samples)

elif stream: # use tool to access the information
# we also pass through the generated fz_image address
if type(stream) is io.BytesIO:
stream = stream.getvalue()
img_prof = TOOLS.image_profile(stream, keep_image=True)
w, h = img_prof["width"], img_prof["height"]
digest = calc_hash(stream)
stream = None # make sure this arg is NOT used
_imgpointer = img_prof["image"] # pointer to fz_image

else: # worst case: must read the file
stream = open(filename, "rb").read()
digest = calc_hash(stream)
img_prof = TOOLS.image_profile(stream, keep_image=True)
w, h = img_prof["width"], img_prof["height"]
stream = None # make sure this arg is NOT used
filename = None # make sure this arg is NOT used
_imgpointer = img_prof["image"] # pointer to fz_image

if pixmap:
w = pixmap.width
h = pixmap.height
alpha = pixmap.alpha
digest = calc_hash(pixmap.samples)
elif stream:
pix = Pixmap(stream)
w = pix.width
h = pix.height
alpha = pix.alpha
digest = calc_hash(pix.samples)
del pix
if type(stream) is io.BytesIO:
stream = stream.getvalue()
else:
pix = Pixmap(filename)
w = pix.width
h = pix.height
alpha = pix.alpha
digest = calc_hash(pix.samples)
del pix

if keep_proportion is True: # for this we need the image dimension
maxf = max(w, h)
fw = w / maxf
fh = h / maxf
Expand Down Expand Up @@ -393,6 +392,7 @@ def calc_matrix(fw, fh, tr, rotate=0):
overlay=overlay,
oc=oc, # optional content object
xref=xref,
alpha=alpha,
_imgname=_imgname, # generated PDF resource name
_imgpointer=_imgpointer, # address of fz_image
)
Expand Down Expand Up @@ -831,7 +831,7 @@ def set_toc_item(
title: OptStr = None,
to: point_like = None,
filename: OptStr = None,
zoom: int = 0,
zoom: float = 0,
) -> None:
"""Update TOC item by index.
Expand Down Expand Up @@ -978,8 +978,8 @@ def getDestStr(xref: int, ddict: dict) -> str:
"""
if not ddict:
return ""
str_goto = "/A<</S/GoTo/D[%i 0 R/XYZ %g %g %i]>>"
str_gotor1 = "/A<</S/GoToR/D[%s /XYZ %s %s %s]/F<</F%s/UF%s/Type/Filespec>>>>"
str_goto = "/A<</S/GoTo/D[%i 0 R/XYZ %g %g %g]>>"
str_gotor1 = "/A<</S/GoToR/D[%s /XYZ %g %g %g]/F<</F%s/UF%s/Type/Filespec>>>>"
str_gotor2 = "/A<</S/GoToR/D%s/F<</F%s/UF%s/Type/Filespec>>>>"
str_launch = "/A<</S/Launch/F<</F%s/UF%s/Type/Filespec>>>>"
str_uri = "/A<</S/URI/URI%s>>"
Expand Down
8 changes: 4 additions & 4 deletions fitz/version.i
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
%pythoncode %{
VersionFitz = "1.18.0"
VersionBind = "1.18.7"
VersionDate = "2021-01-31 00:00:01"
version = (VersionBind, VersionFitz, "202101310001")
%}
VersionBind = "1.18.8"
VersionDate = "2021-02-03 19:56:11"
version = (VersionBind, VersionFitz, "20210203195611")
%}
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ def load_libraries():

setup(
name="PyMuPDF",
version="1.18.7",
version="1.18.8",
description="Python bindings for the PDF rendering library MuPDF",
long_description=long_desc,
classifiers=classifier,
Expand Down

0 comments on commit 444b5eb

Please sign in to comment.