Merge with master

This commit is contained in:
hugovk 2014-09-24 08:50:59 +03:00
commit ab87302560
9 changed files with 136 additions and 19 deletions

View File

@ -40,9 +40,7 @@ script:
- CFLAGS="-coverage" python setup.py build_ext --inplace
- coverage run --append --include=PIL/* selftest.py
# Temporarily remove fail-fast
# - coverage run --append --include=PIL/* -m nose -vx Tests/test_*.py
- coverage run --append --include=PIL/* -m nose -v Tests/test_*.py
- coverage run --append --include=PIL/* -m nose -vx Tests/test_*.py
after_success:
# gather the coverage data

View File

@ -4,6 +4,9 @@ Changelog (Pillow)
2.6.0 (unreleased)
------------------
- Image.tobytes() and Image.tostring() documentation update #916 #917
[mgedmin]
- On Windows, do not execute convert.exe without specifying path #912
[cgohlke]

View File

@ -664,6 +664,10 @@ class Image:
# Declare tostring as alias to tobytes
def tostring(self, *args, **kw):
"""Deprecated alias to tobytes.
.. deprecated:: 2.0
"""
warnings.warn(
'tostring() is deprecated. Please call tobytes() instead.',
DeprecationWarning,

View File

@ -23,23 +23,26 @@ from PIL import Image
class HDC:
"""
Wraps a HDC integer. The resulting object can be passed to the
Wraps an HDC integer. The resulting object can be passed to the
:py:meth:`~PIL.ImageWin.Dib.draw` and :py:meth:`~PIL.ImageWin.Dib.expose`
methods.
"""
def __init__(self, dc):
self.dc = dc
def __int__(self):
return self.dc
class HWND:
"""
Wraps a HWND integer. The resulting object can be passed to the
Wraps an HWND integer. The resulting object can be passed to the
:py:meth:`~PIL.ImageWin.Dib.draw` and :py:meth:`~PIL.ImageWin.Dib.expose`
methods, instead of a DC.
"""
def __init__(self, wnd):
self.wnd = wnd
def __int__(self):
return self.wnd
@ -79,13 +82,12 @@ class Dib:
if image:
self.paste(image)
def expose(self, handle):
"""
Copy the bitmap contents to a device context.
:param handle: Device context (HDC), cast to a Python integer, or a HDC
or HWND instance. In PythonWin, you can use the
:param handle: Device context (HDC), cast to a Python integer, or an
HDC or HWND instance. In PythonWin, you can use the
:py:meth:`CDC.GetHandleAttrib` to get a suitable handle.
"""
if isinstance(handle, HWND):
@ -109,7 +111,7 @@ class Dib:
necessary.
"""
if not src:
src = (0,0) + self.size
src = (0, 0) + self.size
if isinstance(handle, HWND):
dc = self.image.getdc(handle)
try:
@ -120,7 +122,6 @@ class Dib:
result = self.image.draw(handle, dst, src)
return result
def query_palette(self, handle):
"""
Installs the palette associated with the image in the given device
@ -146,7 +147,6 @@ class Dib:
result = self.image.query_palette(handle)
return result
def paste(self, im, box=None):
"""
Paste a PIL image into the bitmap image.
@ -166,7 +166,6 @@ class Dib:
else:
self.image.paste(im.im)
def frombytes(self, buffer):
"""
Load display memory contents from byte data.
@ -176,7 +175,6 @@ class Dib:
"""
return self.image.frombytes(buffer)
def tobytes(self):
"""
Copy display memory contents to bytes object.
@ -204,6 +202,7 @@ class Dib:
)
return self.tobytes()
##
# Create a Window with the given title size.
@ -235,6 +234,7 @@ class Window:
def mainloop(self):
Image.core.eventloop()
##
# Create an image window which displays the given image.

View File

@ -1,16 +1,123 @@
from helper import unittest, PillowTestCase
from helper import unittest, PillowTestCase, hopper
from PIL import Image
from PIL import ImageWin
import sys
class TestImageWin(PillowTestCase):
def test_sanity(self):
dir(Image)
dir(ImageWin)
pass
def test_hdc(self):
# Arrange
dc = 50
# Act
hdc = ImageWin.HDC(dc)
dc2 = int(hdc)
# Assert
self.assertEqual(dc2, 50)
def test_hwnd(self):
# Arrange
wnd = 50
# Act
hwnd = ImageWin.HWND(wnd)
wnd2 = int(hwnd)
# Assert
self.assertEqual(wnd2, 50)
@unittest.skipUnless(sys.platform.startswith('win32'), "Windows only")
class TestImageWinDib(PillowTestCase):
def test_dib_image(self):
# Arrange
im = hopper()
# Act
dib = ImageWin.Dib(im)
# Assert
self.assertEqual(dib.size, im.size)
def test_dib_mode_string(self):
# Arrange
mode = "RGBA"
size = (128, 128)
# Act
dib = ImageWin.Dib(mode, size)
# Assert
self.assertEqual(dib.size, (128, 128))
def test_dib_paste(self):
# Arrange
im = hopper()
mode = "RGBA"
size = (128, 128)
dib = ImageWin.Dib(mode, size)
# Act
dib.paste(im)
# Assert
self.assertEqual(dib.size, (128, 128))
def test_dib_paste_bbox(self):
# Arrange
im = hopper()
bbox = (0, 0, 10, 10)
mode = "RGBA"
size = (128, 128)
dib = ImageWin.Dib(mode, size)
# Act
dib.paste(im, bbox)
# Assert
self.assertEqual(dib.size, (128, 128))
def test_dib_frombytes_tobytes_roundtrip(self):
# Arrange
# Make two different DIB images
im = hopper()
dib1 = ImageWin.Dib(im)
mode = "RGB"
size = (128, 128)
dib2 = ImageWin.Dib(mode, size)
# Confirm they're different
self.assertNotEqual(dib1.tobytes(), dib2.tobytes())
# Act
# Make one the same as the using tobytes()/frombytes()
buffer = dib1.tobytes()
dib2.frombytes(buffer)
# Assert
# Confirm they're the same
self.assertEqual(dib1.tobytes(), dib2.tobytes())
def test_dib_fromstring_tostring_deprecated(self):
# Arrange
im = hopper()
dib = ImageWin.Dib(im)
buffer = dib.tobytes()
# Act/Assert
self.assert_warning(DeprecationWarning, lambda: dib.tostring())
self.assert_warning(DeprecationWarning, lambda: dib.fromstring(buffer))
if __name__ == '__main__':
unittest.main()

View File

@ -135,6 +135,7 @@ ITU-R 709, using the D65 luminant) to the CIE XYZ color space:
.. automethod:: PIL.Image.Image.tell
.. automethod:: PIL.Image.Image.thumbnail
.. automethod:: PIL.Image.Image.tobitmap
.. automethod:: PIL.Image.Image.tobytes
.. automethod:: PIL.Image.Image.tostring
.. automethod:: PIL.Image.Image.transform
.. automethod:: PIL.Image.Image.transpose

View File

@ -535,7 +535,7 @@ PyImaging_ZipEncoderNew(PyObject* self, PyObject* args)
#include "Jpeg.h"
static unsigned int** get_qtables_arrays(PyObject* qtables) {
static unsigned int** get_qtables_arrays(PyObject* qtables, int* qtablesLen) {
PyObject* tables;
PyObject* table;
PyObject* table_data;
@ -588,6 +588,7 @@ static unsigned int** get_qtables_arrays(PyObject* qtables) {
}
Py_DECREF(tables);
*qtablesLen = num_tables;
if (PyErr_Occurred()) {
PyMem_Free(qarrays);
@ -614,6 +615,7 @@ PyImaging_JpegEncoderNew(PyObject* self, PyObject* args)
int subsampling = -1; /* -1=default, 0=none, 1=medium, 2=high */
PyObject* qtables=NULL;
unsigned int **qarrays = NULL;
int qtablesLen = 0;
char* extra = NULL;
int extra_size;
char* rawExif = NULL;
@ -633,7 +635,7 @@ PyImaging_JpegEncoderNew(PyObject* self, PyObject* args)
if (get_packer(encoder, mode, rawmode) < 0)
return NULL;
qarrays = get_qtables_arrays(qtables);
qarrays = get_qtables_arrays(qtables, &qtablesLen);
if (extra && extra_size > 0) {
char* p = malloc(extra_size);
@ -657,6 +659,7 @@ PyImaging_JpegEncoderNew(PyObject* self, PyObject* args)
((JPEGENCODERSTATE*)encoder->state.context)->quality = quality;
((JPEGENCODERSTATE*)encoder->state.context)->qtables = qarrays;
((JPEGENCODERSTATE*)encoder->state.context)->qtablesLen = qtablesLen;
((JPEGENCODERSTATE*)encoder->state.context)->subsampling = subsampling;
((JPEGENCODERSTATE*)encoder->state.context)->progressive = progressive;
((JPEGENCODERSTATE*)encoder->state.context)->smooth = smooth;

View File

@ -90,6 +90,7 @@ typedef struct {
/* Custom quantization tables () */
unsigned int **qtables;
int qtablesLen;
/* Extra data (to be injected after header) */
char* extra; int extra_size;

View File

@ -151,7 +151,7 @@ ImagingJpegEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
if (context->quality > 0) {
quality = context->quality;
}
for (i = 0; i < sizeof(context->qtables)/sizeof(unsigned int); i++) {
for (i = 0; i < context->qtablesLen; i++) {
// TODO: Should add support for none baseline
jpeg_add_quant_table(&context->cinfo, i, context->qtables[i],
quality, TRUE);