merge from master

This commit is contained in:
wiredfool 2014-05-20 08:58:09 -07:00
commit 8d4a77a939
17 changed files with 119 additions and 117 deletions

View File

@ -26,8 +26,14 @@ script:
- coverage erase - coverage erase
- python setup.py clean - python setup.py clean
- python setup.py build_ext --inplace - python setup.py build_ext --inplace
- coverage run --append --include=PIL/* selftest.py
- python Tests/run.py --coverage # Don't cover PyPy: it fails intermittently and is x5.8 slower (#640)
- if [ "$TRAVIS_PYTHON_VERSION" == "pypy" ]; then python selftest.py; fi
- if [ "$TRAVIS_PYTHON_VERSION" == "pypy" ]; then python Tests/run.py; fi
# Cover the others
- if [ "$TRAVIS_PYTHON_VERSION" != "pypy" ]; then coverage run --append --include=PIL/* selftest.py; fi
- if [ "$TRAVIS_PYTHON_VERSION" != "pypy" ]; then python Tests/run.py --coverage; fi
after_success: after_success:
- coverage report - coverage report
@ -37,7 +43,3 @@ after_success:
- pyflakes PIL/*.py - pyflakes PIL/*.py
- pep8 Tests/*.py - pep8 Tests/*.py
- pyflakes Tests/*.py - pyflakes Tests/*.py
matrix:
allow_failures:
- python: "pypy"

View File

@ -4,6 +4,15 @@ Changelog (Pillow)
2.5.0 (unreleased) 2.5.0 (unreleased)
------------------ ------------------
- Remove transparency resource after P->RGBA conversion
[hugovk]
- Clean up preprocessor cruft for Windows
[CounterPillow]
- Adjust Homebrew freetype detection logic
[jacknagel]
- Added Image.close, context manager support. - Added Image.close, context manager support.
[wiredfool] [wiredfool]

View File

@ -818,7 +818,10 @@ class Image:
# can't just retrieve the palette number, got to do it # can't just retrieve the palette number, got to do it
# after quantization. # after quantization.
trns_im = trns_im.convert('RGB') trns_im = trns_im.convert('RGB')
trns = trns_im.getpixel((0, 0)) trns = trns_im.getpixel((0,0))
elif self.mode == 'P' and mode == 'RGBA':
delete_trns = True
if mode == "P" and palette == ADAPTIVE: if mode == "P" and palette == ADAPTIVE:
im = self.im.quantize(colors) im = self.im.quantize(colors)

View File

@ -2,6 +2,7 @@ from tester import *
from PIL import Image from PIL import Image
def test_sanity(): def test_sanity():
def convert(im, mode): def convert(im, mode):
@ -16,6 +17,7 @@ def test_sanity():
for mode in modes: for mode in modes:
yield_test(convert, im, mode) yield_test(convert, im, mode)
def test_default(): def test_default():
im = lena("P") im = lena("P")
@ -26,26 +28,29 @@ def test_default():
assert_image(im, "RGB", im.size) assert_image(im, "RGB", im.size)
# ref https://github.com/python-imaging/Pillow/issues/274 # ref https://github.com/python-imaging/Pillow/issues/274
def _test_float_conversion(im): def _test_float_conversion(im):
orig = im.getpixel((5,5)) orig = im.getpixel((5, 5))
converted = im.convert('F').getpixel((5,5)) converted = im.convert('F').getpixel((5, 5))
assert_equal(orig, converted) assert_equal(orig, converted)
def test_8bit(): def test_8bit():
im = Image.open('Images/lena.jpg') im = Image.open('Images/lena.jpg')
_test_float_conversion(im.convert('L')) _test_float_conversion(im.convert('L'))
def test_16bit(): def test_16bit():
im = Image.open('Tests/images/16bit.cropped.tif') im = Image.open('Tests/images/16bit.cropped.tif')
_test_float_conversion(im) _test_float_conversion(im)
def test_16bit_workaround(): def test_16bit_workaround():
im = Image.open('Tests/images/16bit.cropped.tif') im = Image.open('Tests/images/16bit.cropped.tif')
_test_float_conversion(im.convert('I')) _test_float_conversion(im.convert('I'))
def test_rgba_p(): def test_rgba_p():
im = lena('RGBA') im = lena('RGBA')
im.putalpha(lena('L')) im.putalpha(lena('L'))
@ -54,30 +59,45 @@ def test_rgba_p():
comparable = converted.convert('RGBA') comparable = converted.convert('RGBA')
assert_image_similar(im, comparable, 20) assert_image_similar(im, comparable, 20)
def test_trns_p():
def test_trns_p():
im = lena('P') im = lena('P')
im.info['transparency']=0 im.info['transparency'] = 0
f = tempfile('temp.png') f = tempfile('temp.png')
l = im.convert('L') l = im.convert('L')
assert_equal(l.info['transparency'], 0) # undone assert_equal(l.info['transparency'], 0) # undone
assert_no_exception(lambda: l.save(f)) assert_no_exception(lambda: l.save(f))
rgb = im.convert('RGB') rgb = im.convert('RGB')
assert_equal(rgb.info['transparency'], (0,0,0)) # undone assert_equal(rgb.info['transparency'], (0, 0, 0)) # undone
assert_no_exception(lambda: rgb.save(f)) assert_no_exception(lambda: rgb.save(f))
# ref https://github.com/python-imaging/Pillow/issues/664
def test_trns_p_rgba():
# Arrange
im = lena('P')
im.info['transparency'] = 128
# Act
rgba = im.convert('RGBA')
# Assert
assert_false('transparency' in rgba.info)
def test_trns_l(): def test_trns_l():
im = lena('L') im = lena('L')
im.info['transparency'] = 128 im.info['transparency'] = 128
f = tempfile('temp.png') f = tempfile('temp.png')
rgb = im.convert('RGB') rgb = im.convert('RGB')
assert_equal(rgb.info['transparency'], (128,128,128)) # undone assert_equal(rgb.info['transparency'], (128, 128, 128)) # undone
assert_no_exception(lambda: rgb.save(f)) assert_no_exception(lambda: rgb.save(f))
p = im.convert('P') p = im.convert('P')
@ -85,28 +105,26 @@ def test_trns_l():
assert_no_exception(lambda: p.save(f)) assert_no_exception(lambda: p.save(f))
p = assert_warning(UserWarning, p = assert_warning(UserWarning,
lambda: im.convert('P', palette = Image.ADAPTIVE)) lambda: im.convert('P', palette=Image.ADAPTIVE))
assert_false('transparency' in p.info) assert_false('transparency' in p.info)
assert_no_exception(lambda: p.save(f)) assert_no_exception(lambda: p.save(f))
def test_trns_RGB(): def test_trns_RGB():
im = lena('RGB') im = lena('RGB')
im.info['transparency'] = im.getpixel((0,0)) im.info['transparency'] = im.getpixel((0, 0))
f = tempfile('temp.png') f = tempfile('temp.png')
l = im.convert('L') l = im.convert('L')
assert_equal(l.info['transparency'], l.getpixel((0,0))) # undone assert_equal(l.info['transparency'], l.getpixel((0, 0))) # undone
assert_no_exception(lambda: l.save(f)) assert_no_exception(lambda: l.save(f))
p = im.convert('P') p = im.convert('P')
assert_true('transparency' in p.info) assert_true('transparency' in p.info)
assert_no_exception(lambda: p.save(f)) assert_no_exception(lambda: p.save(f))
p = assert_warning(UserWarning, p = assert_warning(UserWarning,
lambda: im.convert('P', palette = Image.ADAPTIVE)) lambda: im.convert('P', palette=Image.ADAPTIVE))
assert_false('transparency' in p.info) assert_false('transparency' in p.info)
assert_no_exception(lambda: p.save(f)) assert_no_exception(lambda: p.save(f))

View File

@ -3350,7 +3350,7 @@ extern PyObject* PyImaging_ZipEncoderNew(PyObject* self, PyObject* args);
extern PyObject* PyImaging_LibTiffEncoderNew(PyObject* self, PyObject* args); extern PyObject* PyImaging_LibTiffEncoderNew(PyObject* self, PyObject* args);
/* Display support etc (in display.c) */ /* Display support etc (in display.c) */
#ifdef WIN32 #ifdef _WIN32
extern PyObject* PyImaging_CreateWindowWin32(PyObject* self, PyObject* args); extern PyObject* PyImaging_CreateWindowWin32(PyObject* self, PyObject* args);
extern PyObject* PyImaging_DisplayWin32(PyObject* self, PyObject* args); extern PyObject* PyImaging_DisplayWin32(PyObject* self, PyObject* args);
extern PyObject* PyImaging_DisplayModeWin32(PyObject* self, PyObject* args); extern PyObject* PyImaging_DisplayModeWin32(PyObject* self, PyObject* args);
@ -3423,14 +3423,14 @@ static PyMethodDef functions[] = {
/* Memory mapping */ /* Memory mapping */
#ifdef WITH_MAPPING #ifdef WITH_MAPPING
#ifdef WIN32 #ifdef _WIN32
{"map", (PyCFunction)PyImaging_Mapper, 1}, {"map", (PyCFunction)PyImaging_Mapper, 1},
#endif #endif
{"map_buffer", (PyCFunction)PyImaging_MapBuffer, 1}, {"map_buffer", (PyCFunction)PyImaging_MapBuffer, 1},
#endif #endif
/* Display support */ /* Display support */
#ifdef WIN32 #ifdef _WIN32
{"display", (PyCFunction)PyImaging_DisplayWin32, 1}, {"display", (PyCFunction)PyImaging_DisplayWin32, 1},
{"display_mode", (PyCFunction)PyImaging_DisplayModeWin32, 1}, {"display_mode", (PyCFunction)PyImaging_DisplayModeWin32, 1},
{"grabscreen", (PyCFunction)PyImaging_GrabScreenWin32, 1}, {"grabscreen", (PyCFunction)PyImaging_GrabScreenWin32, 1},

View File

@ -28,12 +28,6 @@ http://www.cazabon.com\n\
#include "Imaging.h" #include "Imaging.h"
#include "py3.h" #include "py3.h"
#ifdef WIN32
#include <windows.h>
#include <windef.h>
#include <wingdi.h>
#endif
#define PYCMSVERSION "1.0.0 pil" #define PYCMSVERSION "1.0.0 pil"
/* version history */ /* version history */
@ -450,7 +444,7 @@ cms_profile_is_intent_supported(CmsProfileObject *self, PyObject *args)
return PyInt_FromLong(result != 0); return PyInt_FromLong(result != 0);
} }
#ifdef WIN32 #ifdef _WIN32
static PyObject * static PyObject *
cms_get_display_profile_win32(PyObject* self, PyObject* args) cms_get_display_profile_win32(PyObject* self, PyObject* args)
{ {
@ -496,7 +490,7 @@ static PyMethodDef pyCMSdll_methods[] = {
{"createProfile", createProfile, 1}, {"createProfile", createProfile, 1},
/* platform specific tools */ /* platform specific tools */
#ifdef WIN32 #ifdef _WIN32
{"get_display_profile_win32", cms_get_display_profile_win32, 1}, {"get_display_profile_win32", cms_get_display_profile_win32, 1},
#endif #endif

View File

@ -433,9 +433,6 @@ PyImaging_TiffLzwDecoderNew(PyObject* self, PyObject* args)
#include "TiffDecode.h" #include "TiffDecode.h"
#include <string.h> #include <string.h>
#ifdef __WIN32__
#define strcasecmp(s1, s2) stricmp(s1, s2)
#endif
PyObject* PyObject*
PyImaging_LibTiffDecoderNew(PyObject* self, PyObject* args) PyImaging_LibTiffDecoderNew(PyObject* self, PyObject* args)

View File

@ -31,7 +31,7 @@
/* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */
/* Windows DIB support */ /* Windows DIB support */
#ifdef WIN32 #ifdef _WIN32
#include "ImDib.h" #include "ImDib.h"
@ -864,4 +864,4 @@ error:
return buffer; return buffer;
} }
#endif /* WIN32 */ #endif /* _WIN32 */

View File

@ -670,9 +670,6 @@ PyImaging_JpegEncoderNew(PyObject* self, PyObject* args)
#include "TiffDecode.h" #include "TiffDecode.h"
#include <string.h> #include <string.h>
#ifdef __WIN32__
#define strcasecmp(s1, s2) stricmp(s1, s2)
#endif
PyObject* PyObject*
PyImaging_LibTiffEncoderNew(PyObject* self, PyObject* args) PyImaging_LibTiffEncoderNew(PyObject* self, PyObject* args)

View File

@ -22,7 +22,7 @@
#include "Imaging.h" #include "Imaging.h"
#ifdef WIN32 #ifdef _WIN32
#include "ImDib.h" #include "ImDib.h"
@ -308,4 +308,4 @@ ImagingDeleteDIB(ImagingDIB dib)
free(dib->info); free(dib->info);
} }
#endif /* WIN32 */ #endif /* _WIN32 */

View File

@ -59,7 +59,7 @@ typedef struct {
unsigned char buffer[GIFTABLE]; unsigned char buffer[GIFTABLE];
/* Symbol table */ /* Symbol table */
unsigned INT16 link[GIFTABLE]; UINT16 link[GIFTABLE];
unsigned char data[GIFTABLE]; unsigned char data[GIFTABLE];
int next; int next;

View File

@ -10,20 +10,9 @@
* See the README file for information on usage and redistribution. * See the README file for information on usage and redistribution.
*/ */
#ifdef WIN32 #ifdef _WIN32
#if (defined(_MSC_VER) && _MSC_VER >= 1200) || (defined __GNUC__) #include "ImPlatform.h"
/* already defined in basetsd.h */
#undef INT8
#undef UINT8
#undef INT16
#undef UINT16
#undef INT32
#undef INT64
#undef UINT32
#endif
#include <windows.h>
#if defined(__cplusplus) #if defined(__cplusplus)
extern "C" { extern "C" {

View File

@ -17,26 +17,22 @@
#error Sorry, this library requires ANSI header files. #error Sorry, this library requires ANSI header files.
#endif #endif
#if defined(_MSC_VER) #if defined(_MSC_VER) && !defined(__GNUC__)
#ifndef WIN32 #define inline __inline
#define WIN32
#endif
/* VC++ 4.0 is a bit annoying when it comes to precision issues (like
claiming that "float a = 0.0;" would lead to loss of precision). I
don't like to see warnings from my code, but since I still want to
keep it readable, I simply switch off a few warnings instead of adding
the tons of casts that VC++ seem to require. This code is compiled
with numerous other compilers as well, so any real errors are likely
to be catched anyway. */
#pragma warning(disable: 4244) /* conversion from 'float' to 'int' */
#endif #endif
#if defined(_MSC_VER) #if !defined(PIL_USE_INLINE)
#define inline __inline #define inline
#elif !defined(USE_INLINE)
#define inline
#endif #endif
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#else
/* For System that are not Windows, we'll need to define these. */
#if SIZEOF_SHORT == 2 #if SIZEOF_SHORT == 2
#define INT16 short #define INT16 short
#elif SIZEOF_INT == 2 #elif SIZEOF_INT == 2
@ -61,12 +57,16 @@
#define INT64 long #define INT64 long
#endif #endif
/* assume IEEE; tweak if necessary (patches are welcome) */
#define FLOAT32 float
#define FLOAT64 double
#define INT8 signed char #define INT8 signed char
#define UINT8 unsigned char #define UINT8 unsigned char
#define UINT16 unsigned INT16 #define UINT16 unsigned INT16
#define UINT32 unsigned INT32 #define UINT32 unsigned INT32
#endif
/* assume IEEE; tweak if necessary (patches are welcome) */
#define FLOAT32 float
#define FLOAT64 double

View File

@ -41,7 +41,6 @@
two cases. */ two cases. */
#ifdef _WIN32 #ifdef _WIN32
#include <windows.h>
#include <process.h> #include <process.h>
#else #else
#include <pthread.h> #include <pthread.h>

View File

@ -45,7 +45,7 @@ typedef struct {
unsigned char buffer[LZWTABLE]; unsigned char buffer[LZWTABLE];
/* Symbol table */ /* Symbol table */
unsigned INT16 link[LZWTABLE]; UINT16 link[LZWTABLE];
unsigned char data[LZWTABLE]; unsigned char data[LZWTABLE];
int next; int next;

18
map.c
View File

@ -22,18 +22,6 @@
#include "Imaging.h" #include "Imaging.h"
#ifdef WIN32
#define WIN32_LEAN_AND_MEAN
#undef INT8
#undef UINT8
#undef INT16
#undef UINT16
#undef INT32
#undef INT64
#undef UINT32
#include "windows.h"
#endif
#include "py3.h" #include "py3.h"
/* compatibility wrappers (defined in _imaging.c) */ /* compatibility wrappers (defined in _imaging.c) */
@ -48,7 +36,7 @@ typedef struct {
char* base; char* base;
int size; int size;
int offset; int offset;
#ifdef WIN32 #ifdef _WIN32
HANDLE hFile; HANDLE hFile;
HANDLE hMap; HANDLE hMap;
#endif #endif
@ -71,7 +59,7 @@ PyImaging_MapperNew(const char* filename, int readonly)
mapper->base = NULL; mapper->base = NULL;
mapper->size = mapper->offset = 0; mapper->size = mapper->offset = 0;
#ifdef WIN32 #ifdef _WIN32
mapper->hFile = (HANDLE)-1; mapper->hFile = (HANDLE)-1;
mapper->hMap = (HANDLE)-1; mapper->hMap = (HANDLE)-1;
@ -114,7 +102,7 @@ PyImaging_MapperNew(const char* filename, int readonly)
static void static void
mapping_dealloc(ImagingMapperObject* mapper) mapping_dealloc(ImagingMapperObject* mapper)
{ {
#ifdef WIN32 #ifdef _WIN32
if (mapper->base != 0) if (mapper->base != 0)
UnmapViewOfFile(mapper->base); UnmapViewOfFile(mapper->base);
if (mapper->hMap != (HANDLE)-1) if (mapper->hMap != (HANDLE)-1)

View File

@ -205,25 +205,31 @@ class pil_build_ext(build_ext):
# darwin ports installation directories # darwin ports installation directories
_add_directory(library_dirs, "/opt/local/lib") _add_directory(library_dirs, "/opt/local/lib")
_add_directory(include_dirs, "/opt/local/include") _add_directory(include_dirs, "/opt/local/include")
# if homebrew is installed, use its lib and include directories # if Homebrew is installed, use its lib and include directories
import subprocess import subprocess
try: try:
prefix = subprocess.check_output(['brew', '--prefix']) prefix = subprocess.check_output(['brew', '--prefix']).strip()
if prefix:
prefix = prefix.strip()
_add_directory(library_dirs, os.path.join(prefix, 'lib'))
_add_directory(include_dirs, os.path.join(prefix, 'include'))
# freetype2 is a key-only brew under opt/
_add_directory(library_dirs, os.path.join(prefix, 'opt', 'freetype', 'lib'))
_add_directory(include_dirs, os.path.join(prefix, 'opt', 'freetype', 'include'))
except: except:
pass # homebrew not installed # Homebrew not installed
prefix = None
# freetype2 ships with X11 (after homebrew, so that homebrew freetype is preferred)
_add_directory(library_dirs, "/usr/X11/lib") ft_prefix = None
_add_directory(include_dirs, "/usr/X11/include")
if prefix:
# add Homebrew's include and lib directories
_add_directory(library_dirs, os.path.join(prefix, 'lib'))
_add_directory(include_dirs, os.path.join(prefix, 'include'))
ft_prefix = os.path.join(prefix, 'opt', 'freetype')
if ft_prefix and os.path.isdir(ft_prefix):
# freetype might not be linked into Homebrew's prefix
_add_directory(library_dirs, os.path.join(ft_prefix, 'lib'))
_add_directory(include_dirs, os.path.join(ft_prefix, 'include'))
else:
# fall back to freetype from XQuartz if Homebrew's freetype is missing
_add_directory(library_dirs, "/usr/X11/lib")
_add_directory(include_dirs, "/usr/X11/include")
elif sys.platform.startswith("linux"): elif sys.platform.startswith("linux"):
arch_tp = (plat.processor(), plat.architecture()[0]) arch_tp = (plat.processor(), plat.architecture()[0])