mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-04-14 14:24:13 +03:00
Merge ae5ec03993
into cda26be10e
This commit is contained in:
commit
2a265a1695
|
@ -102,6 +102,31 @@ class TestFileJpeg:
|
|||
assert im.info["comment"] == b"File written by Adobe Photoshop\xa8 4.0\x00"
|
||||
assert im.app["COM"] == im.info["comment"]
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"keep_rgb, no_default_app_segments, expect_app0, expect_app14",
|
||||
(
|
||||
(False, False, True, False),
|
||||
(True, False, False, True),
|
||||
(False, True, False, False),
|
||||
(True, True, False, False),
|
||||
),
|
||||
)
|
||||
def test_default_app_write(
|
||||
self,
|
||||
keep_rgb: bool,
|
||||
no_default_app_segments: bool,
|
||||
expect_app0: bool,
|
||||
expect_app14: bool,
|
||||
) -> None:
|
||||
im = self.roundtrip(
|
||||
hopper(),
|
||||
keep_rgb=keep_rgb,
|
||||
no_default_app_segments=no_default_app_segments,
|
||||
)
|
||||
markers = {m[0] for m in im.applist}
|
||||
assert ("APP0" in markers) == expect_app0
|
||||
assert ("APP14" in markers) == expect_app14
|
||||
|
||||
def test_comment_write(self) -> None:
|
||||
with Image.open(TEST_FILE) as im:
|
||||
assert im.info["comment"] == b"File written by Adobe Photoshop\xa8 4.0\x00"
|
||||
|
|
|
@ -579,6 +579,13 @@ The :py:meth:`~PIL.Image.Image.save` method supports the following options:
|
|||
**exif**
|
||||
If present, the image will be stored with the provided raw EXIF data.
|
||||
|
||||
**no_default_app_segments**
|
||||
If present and true, the image is stored without default JFIF and Adobe
|
||||
application segments. The JFIF segment will still be stored if **dpi**
|
||||
is also specified.
|
||||
|
||||
.. versionadded:: 10.3.0
|
||||
|
||||
**keep_rgb**
|
||||
By default, libjpeg converts images with an RGB color space to YCbCr.
|
||||
If this option is present and true, those images will be stored as RGB
|
||||
|
|
|
@ -90,6 +90,13 @@ raised.
|
|||
API Additions
|
||||
=============
|
||||
|
||||
JPEG app segments
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
When saving JPEG files, ``no_default_app_segments`` can now be set to ``True`` to store
|
||||
the image without default JFIF and Adobe application segments. The JFIF segment will
|
||||
still be stored if ``dpi`` is also specified.
|
||||
|
||||
Added PerspectiveTransform
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
|
|
@ -816,6 +816,7 @@ def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None:
|
|||
info.get("smooth", 0),
|
||||
optimize,
|
||||
info.get("keep_rgb", False),
|
||||
info.get("no_default_app_segments", False),
|
||||
info.get("streamtype", 0),
|
||||
dpi,
|
||||
subsampling,
|
||||
|
|
|
@ -1081,6 +1081,7 @@ PyImaging_JpegEncoderNew(PyObject *self, PyObject *args) {
|
|||
Py_ssize_t smooth = 0;
|
||||
Py_ssize_t optimize = 0;
|
||||
int keep_rgb = 0;
|
||||
int no_default_app_segments = 0;
|
||||
Py_ssize_t streamtype = 0; /* 0=interchange, 1=tables only, 2=image only */
|
||||
Py_ssize_t xdpi = 0, ydpi = 0;
|
||||
Py_ssize_t subsampling = -1; /* -1=default, 0=none, 1=medium, 2=high */
|
||||
|
@ -1098,7 +1099,7 @@ PyImaging_JpegEncoderNew(PyObject *self, PyObject *args) {
|
|||
|
||||
if (!PyArg_ParseTuple(
|
||||
args,
|
||||
"ss|nnnnpn(nn)nnnOz#y#y#",
|
||||
"ss|nnnnppn(nn)nnnOz#y#y#",
|
||||
&mode,
|
||||
&rawmode,
|
||||
&quality,
|
||||
|
@ -1106,6 +1107,7 @@ PyImaging_JpegEncoderNew(PyObject *self, PyObject *args) {
|
|||
&smooth,
|
||||
&optimize,
|
||||
&keep_rgb,
|
||||
&no_default_app_segments,
|
||||
&streamtype,
|
||||
&xdpi,
|
||||
&ydpi,
|
||||
|
@ -1192,6 +1194,7 @@ PyImaging_JpegEncoderNew(PyObject *self, PyObject *args) {
|
|||
JPEGENCODERSTATE *jpeg_encoder_state = (JPEGENCODERSTATE *)encoder->state.context;
|
||||
strncpy(jpeg_encoder_state->rawmode, rawmode, 8);
|
||||
jpeg_encoder_state->keep_rgb = keep_rgb;
|
||||
jpeg_encoder_state->no_default_app_segments = no_default_app_segments;
|
||||
jpeg_encoder_state->quality = quality;
|
||||
jpeg_encoder_state->qtables = qarrays;
|
||||
jpeg_encoder_state->qtablesLen = qtablesLen;
|
||||
|
|
|
@ -77,6 +77,9 @@ typedef struct {
|
|||
/* Disable automatic conversion of RGB images to YCbCr if non-zero */
|
||||
int keep_rgb;
|
||||
|
||||
/* Disable default application segments if non-zero */
|
||||
int no_default_app_segments;
|
||||
|
||||
/* Stream type (0=full, 1=tables only, 2=image only) */
|
||||
int streamtype;
|
||||
|
||||
|
|
|
@ -170,6 +170,13 @@ ImagingJpegEncode(Imaging im, ImagingCodecState state, UINT8 *buf, int bytes) {
|
|||
}
|
||||
}
|
||||
|
||||
/* Disable app markers if the colorspace enabled them.
|
||||
xdpi/ydpi will still override this. */
|
||||
if (context->no_default_app_segments) {
|
||||
context->cinfo.write_JFIF_header = FALSE;
|
||||
context->cinfo.write_Adobe_marker = FALSE;
|
||||
}
|
||||
|
||||
/* Use custom quantization tables */
|
||||
if (context->qtables) {
|
||||
int i;
|
||||
|
|
Loading…
Reference in New Issue
Block a user