Have to guard the ctypes.wintypes import

This commit is contained in:
wiredfool 2015-10-01 14:47:16 +01:00
parent 7a48d7658d
commit eb80824f51

View File

@ -1,113 +1,111 @@
from helper import unittest, PillowTestCase, hopper from helper import unittest, PillowTestCase, hopper
from PIL import Image, ImageWin from PIL import Image, ImageWin
import sys import sys
import ctypes import ctypes
import ctypes.wintypes
from io import BytesIO from io import BytesIO
# see https://github.com/python-pillow/Pillow/pull/1431#issuecomment-144692652 # see https://github.com/python-pillow/Pillow/pull/1431#issuecomment-144692652
if not sys.platform.startswith('win32'): if sys.platform.startswith('win32'):
unittest.skip("Win32 only test") import ctypes.wintypes
class BITMAPFILEHEADER(ctypes.Structure): class BITMAPFILEHEADER(ctypes.Structure):
_pack_ = 2 _pack_ = 2
_fields_ = [ _fields_ = [
('bfType', ctypes.wintypes.WORD), ('bfType', ctypes.wintypes.WORD),
('bfSize', ctypes.wintypes.DWORD), ('bfSize', ctypes.wintypes.DWORD),
('bfReserved1', ctypes.wintypes.WORD), ('bfReserved1', ctypes.wintypes.WORD),
('bfReserved2', ctypes.wintypes.WORD), ('bfReserved2', ctypes.wintypes.WORD),
('bfOffBits', ctypes.wintypes.DWORD), ('bfOffBits', ctypes.wintypes.DWORD),
] ]
class BITMAPINFOHEADER(ctypes.Structure): class BITMAPINFOHEADER(ctypes.Structure):
_pack_ = 2 _pack_ = 2
_fields_ = [ _fields_ = [
('biSize', ctypes.wintypes.DWORD), ('biSize', ctypes.wintypes.DWORD),
('biWidth', ctypes.wintypes.LONG), ('biWidth', ctypes.wintypes.LONG),
('biHeight', ctypes.wintypes.LONG), ('biHeight', ctypes.wintypes.LONG),
('biPlanes', ctypes.wintypes.WORD), ('biPlanes', ctypes.wintypes.WORD),
('biBitCount', ctypes.wintypes.WORD), ('biBitCount', ctypes.wintypes.WORD),
('biCompression', ctypes.wintypes.DWORD), ('biCompression', ctypes.wintypes.DWORD),
('biSizeImage', ctypes.wintypes.DWORD), ('biSizeImage', ctypes.wintypes.DWORD),
('biXPelsPerMeter', ctypes.wintypes.LONG), ('biXPelsPerMeter', ctypes.wintypes.LONG),
('biYPelsPerMeter', ctypes.wintypes.LONG), ('biYPelsPerMeter', ctypes.wintypes.LONG),
('biClrUsed', ctypes.wintypes.DWORD), ('biClrUsed', ctypes.wintypes.DWORD),
('biClrImportant', ctypes.wintypes.DWORD), ('biClrImportant', ctypes.wintypes.DWORD),
] ]
BI_RGB = 0 BI_RGB = 0
DIB_RGB_COLORS = 0 DIB_RGB_COLORS = 0
memcpy = ctypes.cdll.msvcrt.memcpy memcpy = ctypes.cdll.msvcrt.memcpy
memcpy.argtypes = [ ctypes.c_void_p, ctypes.c_void_p, ctypes.c_size_t ] memcpy.argtypes = [ ctypes.c_void_p, ctypes.c_void_p, ctypes.c_size_t ]
CreateCompatibleDC = ctypes.windll.gdi32.CreateCompatibleDC CreateCompatibleDC = ctypes.windll.gdi32.CreateCompatibleDC
CreateCompatibleDC.argtypes = [ ctypes.wintypes.HDC ] CreateCompatibleDC.argtypes = [ ctypes.wintypes.HDC ]
CreateCompatibleDC.restype = ctypes.wintypes.HDC CreateCompatibleDC.restype = ctypes.wintypes.HDC
DeleteDC = ctypes.windll.gdi32.DeleteDC DeleteDC = ctypes.windll.gdi32.DeleteDC
DeleteDC.argtypes = [ ctypes.wintypes.HDC ] DeleteDC.argtypes = [ ctypes.wintypes.HDC ]
SelectObject = ctypes.windll.gdi32.SelectObject SelectObject = ctypes.windll.gdi32.SelectObject
SelectObject.argtypes = [ ctypes.wintypes.HDC, ctypes.wintypes.HGDIOBJ ] SelectObject.argtypes = [ ctypes.wintypes.HDC, ctypes.wintypes.HGDIOBJ ]
SelectObject.restype = ctypes.wintypes.HGDIOBJ SelectObject.restype = ctypes.wintypes.HGDIOBJ
DeleteObject = ctypes.windll.gdi32.DeleteObject DeleteObject = ctypes.windll.gdi32.DeleteObject
DeleteObject.argtypes = [ ctypes.wintypes.HGDIOBJ ] DeleteObject.argtypes = [ ctypes.wintypes.HGDIOBJ ]
CreateDIBSection = ctypes.windll.gdi32.CreateDIBSection CreateDIBSection = ctypes.windll.gdi32.CreateDIBSection
CreateDIBSection.argtypes = [ ctypes.wintypes.HDC, ctypes.c_void_p, ctypes.c_uint, ctypes.POINTER(ctypes.c_void_p), ctypes.wintypes.HANDLE, ctypes.wintypes.DWORD ] CreateDIBSection.argtypes = [ ctypes.wintypes.HDC, ctypes.c_void_p, ctypes.c_uint, ctypes.POINTER(ctypes.c_void_p), ctypes.wintypes.HANDLE, ctypes.wintypes.DWORD ]
CreateDIBSection.restype = ctypes.wintypes.HBITMAP CreateDIBSection.restype = ctypes.wintypes.HBITMAP
def serialize_dib(bi, pixels): def serialize_dib(bi, pixels):
bf = BITMAPFILEHEADER() bf = BITMAPFILEHEADER()
bf.bfType = 0x4d42 bf.bfType = 0x4d42
bf.bfOffBits = ctypes.sizeof(bf) + bi.biSize bf.bfOffBits = ctypes.sizeof(bf) + bi.biSize
bf.bfSize = bf.bfOffBits + bi.biSizeImage bf.bfSize = bf.bfOffBits + bi.biSizeImage
bf.bfReserved1 = bf.bfReserved2 = 0 bf.bfReserved1 = bf.bfReserved2 = 0
buf = (ctypes.c_byte * bf.bfSize)() buf = (ctypes.c_byte * bf.bfSize)()
bp = ctypes.addressof(buf) bp = ctypes.addressof(buf)
memcpy(bp, ctypes.byref(bf), ctypes.sizeof(bf)) memcpy(bp, ctypes.byref(bf), ctypes.sizeof(bf))
memcpy(bp + ctypes.sizeof(bf), ctypes.byref(bi), bi.biSize) memcpy(bp + ctypes.sizeof(bf), ctypes.byref(bi), bi.biSize)
memcpy(bp + bf.bfOffBits, pixels, bi.biSizeImage) memcpy(bp + bf.bfOffBits, pixels, bi.biSizeImage)
return bytes(buf) return bytes(buf)
class TestImageWinPointers(PillowTestCase): class TestImageWinPointers(PillowTestCase):
def test_pointer(self): def test_pointer(self):
im = hopper() im = hopper()
(width, height) =im.size (width, height) =im.size
opath = self.tempfile('temp.png') opath = self.tempfile('temp.png')
imdib = ImageWin.Dib(im) imdib = ImageWin.Dib(im)
hdr = BITMAPINFOHEADER() hdr = BITMAPINFOHEADER()
hdr.biSize = ctypes.sizeof(hdr) hdr.biSize = ctypes.sizeof(hdr)
hdr.biWidth = width hdr.biWidth = width
hdr.biHeight = height hdr.biHeight = height
hdr.biPlanes = 1 hdr.biPlanes = 1
hdr.biBitCount = 32 hdr.biBitCount = 32
hdr.biCompression = BI_RGB hdr.biCompression = BI_RGB
hdr.biSizeImage = width * height * 4 hdr.biSizeImage = width * height * 4
hdr.biClrUsed = 0 hdr.biClrUsed = 0
hdr.biClrImportant = 0 hdr.biClrImportant = 0
hdc = CreateCompatibleDC(None) hdc = CreateCompatibleDC(None)
#print('hdc:',hex(hdc)) #print('hdc:',hex(hdc))
pixels = ctypes.c_void_p() pixels = ctypes.c_void_p()
dib = CreateDIBSection(hdc, ctypes.byref(hdr), DIB_RGB_COLORS, ctypes.byref(pixels), None, 0) dib = CreateDIBSection(hdc, ctypes.byref(hdr), DIB_RGB_COLORS, ctypes.byref(pixels), None, 0)
SelectObject(hdc, dib) SelectObject(hdc, dib)
imdib.expose(hdc) imdib.expose(hdc)
bitmap = serialize_dib(hdr, pixels) bitmap = serialize_dib(hdr, pixels)
DeleteObject(dib) DeleteObject(dib)
DeleteDC(hdc) DeleteDC(hdc)
reloaded = Image.open(BytesIO(bitmap)).save(opath) reloaded = Image.open(BytesIO(bitmap)).save(opath)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
# End of file