mirror of
				https://github.com/python-pillow/Pillow.git
				synced 2025-11-04 01:47:47 +03:00 
			
		
		
		
	Test for PR#1431, following [nu744]
This commit is contained in:
		
							parent
							
								
									2be12dec2b
								
							
						
					
					
						commit
						3228860514
					
				
							
								
								
									
										113
									
								
								Tests/test_imagewin_pointers.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								Tests/test_imagewin_pointers.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,113 @@
 | 
			
		|||
from helper import unittest, PillowTestCase, hopper
 | 
			
		||||
 | 
			
		||||
from PIL import Image, ImageWin
 | 
			
		||||
import sys
 | 
			
		||||
import ctypes
 | 
			
		||||
import ctypes.wintypes
 | 
			
		||||
from io import BytesIO
 | 
			
		||||
 | 
			
		||||
# see https://github.com/python-pillow/Pillow/pull/1431#issuecomment-144692652
 | 
			
		||||
 | 
			
		||||
if not sys.platform.startswith('win32'):
 | 
			
		||||
	unittest.skip("Win32 only test")
 | 
			
		||||
 | 
			
		||||
class BITMAPFILEHEADER(ctypes.Structure):
 | 
			
		||||
    _pack_ = 2
 | 
			
		||||
    _fields_ = [
 | 
			
		||||
        ('bfType', ctypes.wintypes.WORD),
 | 
			
		||||
        ('bfSize', ctypes.wintypes.DWORD),
 | 
			
		||||
        ('bfReserved1', ctypes.wintypes.WORD),
 | 
			
		||||
        ('bfReserved2', ctypes.wintypes.WORD),
 | 
			
		||||
        ('bfOffBits', ctypes.wintypes.DWORD),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
class BITMAPINFOHEADER(ctypes.Structure):
 | 
			
		||||
    _pack_ = 2
 | 
			
		||||
    _fields_ = [
 | 
			
		||||
        ('biSize', ctypes.wintypes.DWORD),
 | 
			
		||||
        ('biWidth', ctypes.wintypes.LONG),
 | 
			
		||||
        ('biHeight', ctypes.wintypes.LONG),
 | 
			
		||||
        ('biPlanes', ctypes.wintypes.WORD),
 | 
			
		||||
        ('biBitCount', ctypes.wintypes.WORD),
 | 
			
		||||
        ('biCompression', ctypes.wintypes.DWORD),
 | 
			
		||||
        ('biSizeImage', ctypes.wintypes.DWORD),
 | 
			
		||||
        ('biXPelsPerMeter', ctypes.wintypes.LONG),
 | 
			
		||||
        ('biYPelsPerMeter', ctypes.wintypes.LONG),
 | 
			
		||||
        ('biClrUsed', ctypes.wintypes.DWORD),
 | 
			
		||||
        ('biClrImportant', ctypes.wintypes.DWORD),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
BI_RGB = 0
 | 
			
		||||
DIB_RGB_COLORS = 0
 | 
			
		||||
 | 
			
		||||
memcpy = ctypes.cdll.msvcrt.memcpy
 | 
			
		||||
memcpy.argtypes = [ ctypes.c_void_p, ctypes.c_void_p, ctypes.c_size_t ]
 | 
			
		||||
 | 
			
		||||
CreateCompatibleDC = ctypes.windll.gdi32.CreateCompatibleDC
 | 
			
		||||
CreateCompatibleDC.argtypes = [ ctypes.wintypes.HDC ]
 | 
			
		||||
CreateCompatibleDC.restype = ctypes.wintypes.HDC
 | 
			
		||||
 | 
			
		||||
DeleteDC = ctypes.windll.gdi32.DeleteDC
 | 
			
		||||
DeleteDC.argtypes = [ ctypes.wintypes.HDC ]
 | 
			
		||||
 | 
			
		||||
SelectObject = ctypes.windll.gdi32.SelectObject
 | 
			
		||||
SelectObject.argtypes = [ ctypes.wintypes.HDC, ctypes.wintypes.HGDIOBJ ]
 | 
			
		||||
SelectObject.restype = ctypes.wintypes.HGDIOBJ
 | 
			
		||||
 | 
			
		||||
DeleteObject = ctypes.windll.gdi32.DeleteObject
 | 
			
		||||
DeleteObject.argtypes = [ ctypes.wintypes.HGDIOBJ ]
 | 
			
		||||
 | 
			
		||||
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.restype = ctypes.wintypes.HBITMAP
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def serialize_dib(bi, pixels):
 | 
			
		||||
    bf = BITMAPFILEHEADER()
 | 
			
		||||
    bf.bfType = 0x4d42
 | 
			
		||||
    bf.bfOffBits = ctypes.sizeof(bf) + bi.biSize
 | 
			
		||||
    bf.bfSize = bf.bfOffBits + bi.biSizeImage
 | 
			
		||||
    bf.bfReserved1 = bf.bfReserved2 = 0
 | 
			
		||||
 | 
			
		||||
    buf = (ctypes.c_byte * bf.bfSize)()
 | 
			
		||||
    bp = ctypes.addressof(buf)
 | 
			
		||||
    memcpy(bp, ctypes.byref(bf), ctypes.sizeof(bf))
 | 
			
		||||
    memcpy(bp + ctypes.sizeof(bf), ctypes.byref(bi), bi.biSize)
 | 
			
		||||
    memcpy(bp + bf.bfOffBits, pixels, bi.biSizeImage)
 | 
			
		||||
    return bytes(buf)
 | 
			
		||||
 | 
			
		||||
class TestImageWinPointers(PillowTestCase):
 | 
			
		||||
	def test_pointer(self):
 | 
			
		||||
		im = hopper()
 | 
			
		||||
		(width, height) =im.size
 | 
			
		||||
		opath = self.tempfile('temp.png')
 | 
			
		||||
		imdib = ImageWin.Dib(im)
 | 
			
		||||
 | 
			
		||||
		hdr = BITMAPINFOHEADER()
 | 
			
		||||
		hdr.biSize = ctypes.sizeof(hdr)
 | 
			
		||||
		hdr.biWidth = width
 | 
			
		||||
		hdr.biHeight = height
 | 
			
		||||
		hdr.biPlanes = 1
 | 
			
		||||
		hdr.biBitCount = 32
 | 
			
		||||
		hdr.biCompression = BI_RGB
 | 
			
		||||
		hdr.biSizeImage = width * height * 4
 | 
			
		||||
		hdr.biClrUsed = 0
 | 
			
		||||
		hdr.biClrImportant = 0
 | 
			
		||||
 | 
			
		||||
		hdc = CreateCompatibleDC(None)
 | 
			
		||||
		print('hdc:',hex(hdc))
 | 
			
		||||
		pixels = ctypes.c_void_p()
 | 
			
		||||
		dib = CreateDIBSection(hdc, ctypes.byref(hdr), DIB_RGB_COLORS, ctypes.byref(pixels), None, 0)
 | 
			
		||||
		SelectObject(hdc, dib)
 | 
			
		||||
 | 
			
		||||
		imdib.expose(hdc)
 | 
			
		||||
		bitmap = serialize_dib(hdr, pixels)
 | 
			
		||||
		DeleteObject(dib)
 | 
			
		||||
		DeleteDC(hdc)
 | 
			
		||||
 | 
			
		||||
		reloaded = Image.open(BytesIO(bitmap)).save(opath)
 | 
			
		||||
 | 
			
		||||
if __name__ == '__main__':
 | 
			
		||||
    unittest.main()
 | 
			
		||||
 | 
			
		||||
# End of file
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user