pyglet 2.1.3__py3-none-any.whl → 2.1.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pyglet/__init__.py +21 -9
- pyglet/__init__.pyi +3 -1
- pyglet/app/cocoa.py +6 -3
- pyglet/display/win32.py +14 -15
- pyglet/display/xlib_vidmoderestore.py +1 -1
- pyglet/extlibs/earcut.py +2 -2
- pyglet/font/__init__.py +3 -3
- pyglet/font/base.py +118 -51
- pyglet/font/dwrite/__init__.py +1381 -0
- pyglet/font/dwrite/d2d1_lib.py +637 -0
- pyglet/font/dwrite/d2d1_types_lib.py +60 -0
- pyglet/font/dwrite/dwrite_lib.py +1577 -0
- pyglet/font/fontconfig.py +79 -16
- pyglet/font/freetype.py +252 -77
- pyglet/font/freetype_lib.py +234 -125
- pyglet/font/harfbuzz/__init__.py +275 -0
- pyglet/font/harfbuzz/harfbuzz_lib.py +212 -0
- pyglet/font/quartz.py +432 -112
- pyglet/font/user.py +18 -11
- pyglet/font/win32.py +9 -1
- pyglet/gl/wgl.py +94 -87
- pyglet/gl/wglext_arb.py +472 -218
- pyglet/gl/wglext_nv.py +410 -188
- pyglet/gui/widgets.py +6 -1
- pyglet/image/codecs/bmp.py +3 -5
- pyglet/image/codecs/gdiplus.py +28 -9
- pyglet/image/codecs/wic.py +198 -489
- pyglet/image/codecs/wincodec_lib.py +413 -0
- pyglet/input/base.py +3 -2
- pyglet/input/macos/darwin_hid.py +28 -2
- pyglet/input/win32/directinput.py +2 -1
- pyglet/input/win32/xinput.py +10 -9
- pyglet/lib.py +14 -2
- pyglet/libs/darwin/cocoapy/cocoalibs.py +74 -3
- pyglet/libs/darwin/coreaudio.py +0 -2
- pyglet/libs/win32/__init__.py +4 -2
- pyglet/libs/win32/com.py +65 -12
- pyglet/libs/win32/constants.py +1 -0
- pyglet/libs/win32/dinput.py +1 -9
- pyglet/libs/win32/types.py +72 -8
- pyglet/media/codecs/coreaudio.py +1 -0
- pyglet/media/codecs/wmf.py +93 -72
- pyglet/media/devices/win32.py +5 -4
- pyglet/media/drivers/directsound/lib_dsound.py +4 -4
- pyglet/media/drivers/xaudio2/interface.py +21 -17
- pyglet/media/drivers/xaudio2/lib_xaudio2.py +42 -25
- pyglet/shapes.py +1 -1
- pyglet/text/document.py +7 -53
- pyglet/text/formats/attributed.py +3 -1
- pyglet/text/formats/plaintext.py +1 -1
- pyglet/text/formats/structured.py +1 -1
- pyglet/text/layout/base.py +76 -68
- pyglet/text/layout/incremental.py +38 -8
- pyglet/text/layout/scrolling.py +1 -1
- pyglet/text/runlist.py +2 -114
- pyglet/window/win32/__init__.py +1 -3
- {pyglet-2.1.3.dist-info → pyglet-2.1.4.dist-info}/METADATA +1 -1
- {pyglet-2.1.3.dist-info → pyglet-2.1.4.dist-info}/RECORD +60 -54
- pyglet/font/directwrite.py +0 -2798
- {pyglet-2.1.3.dist-info → pyglet-2.1.4.dist-info}/LICENSE +0 -0
- {pyglet-2.1.3.dist-info → pyglet-2.1.4.dist-info}/WHEEL +0 -0
pyglet/image/codecs/wic.py
CHANGED
|
@@ -1,421 +1,182 @@
|
|
|
1
|
-
from
|
|
2
|
-
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
from ctypes import byref, memmove
|
|
5
|
+
from typing import BinaryIO, Sequence
|
|
6
|
+
|
|
7
|
+
from pyglet.image import ImageData
|
|
8
|
+
from pyglet.image.codecs import ImageDecodeException, ImageDecoder, ImageEncoder
|
|
9
|
+
from pyglet.image.codecs.wincodec_lib import (
|
|
10
|
+
CLSID_WICImagingFactory1,
|
|
11
|
+
CLSID_WICImagingFactory2,
|
|
12
|
+
GUID_ContainerFormatBmp,
|
|
13
|
+
GUID_ContainerFormatJpeg,
|
|
14
|
+
GUID_ContainerFormatPng,
|
|
15
|
+
GUID_ContainerFormatTiff,
|
|
16
|
+
GUID_ContainerFormatWmp,
|
|
17
|
+
GUID_WICPixelFormat24bppBGR,
|
|
18
|
+
GUID_WICPixelFormat32bppBGRA,
|
|
19
|
+
IID_IWICImagingFactory1,
|
|
20
|
+
IID_IWICImagingFactory2,
|
|
21
|
+
IPropertyBag2,
|
|
22
|
+
IWICBitmap,
|
|
23
|
+
IWICBitmapDecoder,
|
|
24
|
+
IWICBitmapEncoder,
|
|
25
|
+
IWICBitmapFlipRotator,
|
|
26
|
+
IWICBitmapFrameDecode,
|
|
27
|
+
IWICBitmapFrameEncode,
|
|
28
|
+
IWICFormatConverter,
|
|
29
|
+
IWICImagingFactory,
|
|
30
|
+
IWICImagingFactory2,
|
|
31
|
+
IWICMetadataQueryReader,
|
|
32
|
+
IWICStream,
|
|
33
|
+
WICBitmapCacheOnDemand,
|
|
34
|
+
WICBitmapDitherTypeNone,
|
|
35
|
+
WICBitmapEncoderNoCache,
|
|
36
|
+
WICBitmapPaletteTypeCustom,
|
|
37
|
+
WICBitmapTransformFlipVertical,
|
|
38
|
+
WICDecodeMetadataCacheOnDemand,
|
|
39
|
+
)
|
|
3
40
|
from pyglet.libs.win32 import _kernel32 as kernel32
|
|
4
41
|
from pyglet.libs.win32 import _ole32 as ole32
|
|
5
|
-
from pyglet.libs.win32
|
|
6
|
-
from pyglet.libs.win32.
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
(
|
|
106
|
-
|
|
107
|
-
(
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
('IsBlackWhite',
|
|
129
|
-
com.STDMETHOD()),
|
|
130
|
-
('IsGrayscale',
|
|
131
|
-
com.STDMETHOD()),
|
|
132
|
-
('HasAlpha',
|
|
133
|
-
com.STDMETHOD()),
|
|
134
|
-
]
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
class IWICStream(IStream, com.pIUnknown):
|
|
138
|
-
_methods_ = [
|
|
139
|
-
('InitializeFromIStream',
|
|
140
|
-
com.STDMETHOD(IStream)),
|
|
141
|
-
('InitializeFromFilename',
|
|
142
|
-
com.STDMETHOD(LPCWSTR, DWORD)),
|
|
143
|
-
('InitializeFromMemory',
|
|
144
|
-
com.STDMETHOD(POINTER(BYTE), DWORD)),
|
|
145
|
-
('InitializeFromIStreamRegion',
|
|
146
|
-
com.STDMETHOD()),
|
|
147
|
-
]
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
class IWICBitmapFrameEncode(com.pIUnknown):
|
|
151
|
-
_methods_ = [
|
|
152
|
-
('Initialize',
|
|
153
|
-
com.STDMETHOD(IPropertyBag2)),
|
|
154
|
-
('SetSize',
|
|
155
|
-
com.STDMETHOD(UINT, UINT)),
|
|
156
|
-
('SetResolution',
|
|
157
|
-
com.STDMETHOD()),
|
|
158
|
-
('SetPixelFormat',
|
|
159
|
-
com.STDMETHOD(REFWICPixelFormatGUID)),
|
|
160
|
-
('SetColorContexts',
|
|
161
|
-
com.STDMETHOD()),
|
|
162
|
-
('SetPalette',
|
|
163
|
-
com.STDMETHOD(IWICPalette)),
|
|
164
|
-
('SetThumbnail',
|
|
165
|
-
com.STDMETHOD()),
|
|
166
|
-
('WritePixels',
|
|
167
|
-
com.STDMETHOD(UINT, UINT, UINT, POINTER(BYTE))),
|
|
168
|
-
('WriteSource',
|
|
169
|
-
com.STDMETHOD()),
|
|
170
|
-
('Commit',
|
|
171
|
-
com.STDMETHOD()),
|
|
172
|
-
('GetMetadataQueryWriter',
|
|
173
|
-
com.STDMETHOD())
|
|
174
|
-
]
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
class IWICBitmapEncoder(com.pIUnknown):
|
|
178
|
-
_methods_ = [
|
|
179
|
-
('Initialize',
|
|
180
|
-
com.STDMETHOD(IWICStream, WICBitmapEncoderCacheOption)),
|
|
181
|
-
('GetContainerFormat',
|
|
182
|
-
com.STDMETHOD()),
|
|
183
|
-
('GetEncoderInfo',
|
|
184
|
-
com.STDMETHOD()),
|
|
185
|
-
('SetColorContexts',
|
|
186
|
-
com.STDMETHOD()),
|
|
187
|
-
('SetPalette',
|
|
188
|
-
com.STDMETHOD()),
|
|
189
|
-
('SetThumbnail',
|
|
190
|
-
com.STDMETHOD()),
|
|
191
|
-
('SetPreview',
|
|
192
|
-
com.STDMETHOD()),
|
|
193
|
-
('CreateNewFrame',
|
|
194
|
-
com.STDMETHOD(POINTER(IWICBitmapFrameEncode), POINTER(IPropertyBag2))),
|
|
195
|
-
('Commit',
|
|
196
|
-
com.STDMETHOD()),
|
|
197
|
-
('GetMetadataQueryWriter',
|
|
198
|
-
com.STDMETHOD())
|
|
199
|
-
]
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
class IWICComponentInfo(com.pIUnknown):
|
|
203
|
-
_methods_ = [
|
|
204
|
-
('GetComponentType',
|
|
205
|
-
com.STDMETHOD()),
|
|
206
|
-
('GetCLSID',
|
|
207
|
-
com.STDMETHOD()),
|
|
208
|
-
('GetSigningStatus',
|
|
209
|
-
com.STDMETHOD()),
|
|
210
|
-
('GetAuthor',
|
|
211
|
-
com.STDMETHOD()),
|
|
212
|
-
('GetVendorGUID',
|
|
213
|
-
com.STDMETHOD()),
|
|
214
|
-
('GetVersion',
|
|
215
|
-
com.STDMETHOD()),
|
|
216
|
-
('GetSpecVersion',
|
|
217
|
-
com.STDMETHOD()),
|
|
218
|
-
('GetFriendlyName',
|
|
219
|
-
com.STDMETHOD())
|
|
220
|
-
]
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
class IWICPixelFormatInfo(IWICComponentInfo, com.pIUnknown):
|
|
224
|
-
_methods_ = [
|
|
225
|
-
('GetFormatGUID',
|
|
226
|
-
com.STDMETHOD(POINTER(com.GUID))),
|
|
227
|
-
('GetColorContext',
|
|
228
|
-
com.STDMETHOD()),
|
|
229
|
-
('GetBitsPerPixel',
|
|
230
|
-
com.STDMETHOD(POINTER(UINT))),
|
|
231
|
-
('GetChannelCount',
|
|
232
|
-
com.STDMETHOD(POINTER(UINT))),
|
|
233
|
-
('GetChannelMask',
|
|
234
|
-
com.STDMETHOD())
|
|
235
|
-
]
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
class IWICBitmapSource(com.pIUnknown):
|
|
239
|
-
_methods_ = [
|
|
240
|
-
('GetSize',
|
|
241
|
-
com.STDMETHOD(POINTER(UINT), POINTER(UINT))),
|
|
242
|
-
('GetPixelFormat',
|
|
243
|
-
com.STDMETHOD(REFWICPixelFormatGUID)),
|
|
244
|
-
('GetResolution',
|
|
245
|
-
com.STDMETHOD(POINTER(DOUBLE), POINTER(DOUBLE))),
|
|
246
|
-
('CopyPalette',
|
|
247
|
-
com.STDMETHOD()),
|
|
248
|
-
('CopyPixels',
|
|
249
|
-
com.STDMETHOD(c_void_p, UINT, UINT, c_void_p)),
|
|
250
|
-
]
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
class IWICFormatConverter(IWICBitmapSource, com.pIUnknown):
|
|
254
|
-
_methods_ = [
|
|
255
|
-
('Initialize',
|
|
256
|
-
com.STDMETHOD(IWICBitmapSource, REFWICPixelFormatGUID, WICBitmapDitherType, c_void_p, DOUBLE,
|
|
257
|
-
WICBitmapPaletteType)),
|
|
258
|
-
('CanConvert',
|
|
259
|
-
com.STDMETHOD(REFWICPixelFormatGUID, REFWICPixelFormatGUID, POINTER(BOOL))),
|
|
260
|
-
]
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
class IWICMetadataQueryReader(com.pIUnknown):
|
|
264
|
-
_methods_ = [
|
|
265
|
-
('GetContainerFormat',
|
|
266
|
-
com.STDMETHOD()),
|
|
267
|
-
('GetLocation',
|
|
268
|
-
com.STDMETHOD()),
|
|
269
|
-
('GetMetadataByName',
|
|
270
|
-
com.STDMETHOD(LPCWSTR, c_void_p)),
|
|
271
|
-
('GetEnumerator',
|
|
272
|
-
com.STDMETHOD()),
|
|
273
|
-
]
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
class IWICBitmapFrameDecode(IWICBitmapSource, com.pIUnknown):
|
|
277
|
-
_methods_ = [
|
|
278
|
-
('GetMetadataQueryReader',
|
|
279
|
-
com.STDMETHOD(POINTER(IWICMetadataQueryReader))),
|
|
280
|
-
('GetColorContexts',
|
|
281
|
-
com.STDMETHOD()),
|
|
282
|
-
('GetThumbnail',
|
|
283
|
-
com.STDMETHOD(POINTER(IWICBitmapSource))),
|
|
284
|
-
]
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
class IWICBitmapFlipRotator(IWICBitmapSource, com.pIUnknown):
|
|
288
|
-
_methods_ = [
|
|
289
|
-
('Initialize',
|
|
290
|
-
com.STDMETHOD(IWICBitmapSource, WICBitmapTransformOptions)),
|
|
291
|
-
]
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
class IWICBitmap(IWICBitmapSource, com.pIUnknown):
|
|
295
|
-
_methods_ = [
|
|
296
|
-
('Lock',
|
|
297
|
-
com.STDMETHOD()),
|
|
298
|
-
('SetPalette',
|
|
299
|
-
com.STDMETHOD()),
|
|
300
|
-
('SetResolution',
|
|
301
|
-
com.STDMETHOD())
|
|
302
|
-
]
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
class IWICBitmapDecoder(com.pIUnknown):
|
|
306
|
-
_methods_ = [
|
|
307
|
-
('QueryCapability',
|
|
308
|
-
com.STDMETHOD()),
|
|
309
|
-
('Initialize',
|
|
310
|
-
com.STDMETHOD()),
|
|
311
|
-
('GetContainerFormat',
|
|
312
|
-
com.STDMETHOD()),
|
|
313
|
-
('GetDecoderInfo',
|
|
314
|
-
com.STDMETHOD()),
|
|
315
|
-
('CopyPalette',
|
|
316
|
-
com.STDMETHOD()),
|
|
317
|
-
('GetMetadataQueryReader',
|
|
318
|
-
com.STDMETHOD(POINTER(IWICMetadataQueryReader))),
|
|
319
|
-
('GetPreview',
|
|
320
|
-
com.STDMETHOD()),
|
|
321
|
-
('GetColorContexts',
|
|
322
|
-
com.STDMETHOD()),
|
|
323
|
-
('GetThumbnail',
|
|
324
|
-
com.STDMETHOD()),
|
|
325
|
-
('GetFrameCount',
|
|
326
|
-
com.STDMETHOD(POINTER(UINT))),
|
|
327
|
-
('GetFrame',
|
|
328
|
-
com.STDMETHOD(UINT, POINTER(IWICBitmapFrameDecode))),
|
|
329
|
-
]
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
IID_IWICImagingFactory1 = com.GUID(0xec5ec8a9, 0xc395, 0x4314, 0x9c, 0x77, 0x54, 0xd7, 0xa9, 0x35, 0xff, 0x70)
|
|
333
|
-
IID_IWICImagingFactory2 = com.GUID(0x7B816B45, 0x1996, 0x4476, 0xB1, 0x32, 0xDE, 0x9E, 0x24, 0x7C, 0x8A, 0xF0)
|
|
334
|
-
|
|
335
|
-
if WINDOWS_8_OR_GREATER:
|
|
336
|
-
IID_IWICImagingFactory = IID_IWICImagingFactory2
|
|
337
|
-
else:
|
|
338
|
-
IID_IWICImagingFactory = IID_IWICImagingFactory1
|
|
339
|
-
|
|
340
|
-
IID_IWICPixelFormatInfo = com.GUID(0xE8EDA601, 0x3D48, 0x431a, 0xAB, 0x44, 0x69, 0x05, 0x9B, 0xE8, 0x8B, 0xBE)
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
class IWICImagingFactory(com.pIUnknown):
|
|
344
|
-
_methods_ = [
|
|
345
|
-
('CreateDecoderFromFilename',
|
|
346
|
-
com.STDMETHOD(LPCWSTR, com.GUID, DWORD, WICDecodeOptions, POINTER(IWICBitmapDecoder))),
|
|
347
|
-
('CreateDecoderFromStream',
|
|
348
|
-
com.STDMETHOD(com.pIUnknown, c_void_p, WICDecodeOptions, POINTER(IWICBitmapDecoder))),
|
|
349
|
-
('CreateDecoderFromFileHandle',
|
|
350
|
-
com.STDMETHOD()),
|
|
351
|
-
('CreateComponentInfo',
|
|
352
|
-
com.STDMETHOD(com.GUID, POINTER(IWICComponentInfo))),
|
|
353
|
-
('CreateDecoder',
|
|
354
|
-
com.STDMETHOD()),
|
|
355
|
-
('CreateEncoder',
|
|
356
|
-
com.STDMETHOD(POINTER(com.GUID), POINTER(com.GUID), POINTER(IWICBitmapEncoder))),
|
|
357
|
-
('CreatePalette',
|
|
358
|
-
com.STDMETHOD(POINTER(IWICPalette))),
|
|
359
|
-
('CreateFormatConverter',
|
|
360
|
-
com.STDMETHOD(POINTER(IWICFormatConverter))),
|
|
361
|
-
('CreateBitmapScaler',
|
|
362
|
-
com.STDMETHOD()),
|
|
363
|
-
('CreateBitmapClipper',
|
|
364
|
-
com.STDMETHOD()),
|
|
365
|
-
('CreateBitmapFlipRotator',
|
|
366
|
-
com.STDMETHOD(POINTER(IWICBitmapFlipRotator))),
|
|
367
|
-
('CreateStream',
|
|
368
|
-
com.STDMETHOD(POINTER(IWICStream))),
|
|
369
|
-
('CreateColorContext',
|
|
370
|
-
com.STDMETHOD()),
|
|
371
|
-
('CreateColorTransformer',
|
|
372
|
-
com.STDMETHOD()),
|
|
373
|
-
('CreateBitmap',
|
|
374
|
-
com.STDMETHOD(UINT, UINT, REFWICPixelFormatGUID, WICBitmapCreateCacheOption, POINTER(IWICBitmap))),
|
|
375
|
-
('CreateBitmapFromSource',
|
|
376
|
-
com.STDMETHOD()),
|
|
377
|
-
('CreateBitmapFromSourceRect',
|
|
378
|
-
com.STDMETHOD()),
|
|
379
|
-
('CreateBitmapFromMemory',
|
|
380
|
-
com.STDMETHOD(UINT, UINT, REFWICPixelFormatGUID, UINT, UINT, POINTER(BYTE), POINTER(IWICBitmap))),
|
|
381
|
-
('CreateBitmapFromHBITMAP',
|
|
382
|
-
com.STDMETHOD()),
|
|
383
|
-
('CreateBitmapFromHICON',
|
|
384
|
-
com.STDMETHOD()),
|
|
385
|
-
('CreateComponentEnumerator',
|
|
386
|
-
com.STDMETHOD()),
|
|
387
|
-
('CreateFastMetadataEncoderFromDecoder',
|
|
388
|
-
com.STDMETHOD()),
|
|
389
|
-
('CreateFastMetadataEncoderFromFrameDecode',
|
|
390
|
-
com.STDMETHOD()),
|
|
391
|
-
('CreateQueryWriter',
|
|
392
|
-
com.STDMETHOD()),
|
|
393
|
-
('CreateQueryWriterFromReader',
|
|
394
|
-
com.STDMETHOD())
|
|
395
|
-
]
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
_factory = IWICImagingFactory()
|
|
399
|
-
|
|
400
|
-
ole32.CoCreateInstance(CLSID_WICImagingFactory,
|
|
401
|
-
None,
|
|
402
|
-
CLSCTX_INPROC_SERVER,
|
|
403
|
-
IID_IWICImagingFactory,
|
|
404
|
-
byref(_factory))
|
|
42
|
+
from pyglet.libs.win32 import com
|
|
43
|
+
from pyglet.libs.win32.constants import (
|
|
44
|
+
CLSCTX_INPROC_SERVER,
|
|
45
|
+
GENERIC_WRITE,
|
|
46
|
+
GMEM_MOVEABLE,
|
|
47
|
+
STREAM_SEEK_SET,
|
|
48
|
+
)
|
|
49
|
+
from pyglet.libs.win32.types import BOOL, BYTE, PROPVARIANT, STATSTG, UINT, ULONG, IStream
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _create_factory() -> IWICImagingFactory2 | IWICImagingFactory | None:
|
|
53
|
+
"""Get a WIC Factory.
|
|
54
|
+
|
|
55
|
+
Factory 2 should be available since Windows 7 with a Platform Update, but be on the safe side.
|
|
56
|
+
"""
|
|
57
|
+
try:
|
|
58
|
+
factory = IWICImagingFactory2()
|
|
59
|
+
ole32.CoCreateInstance(CLSID_WICImagingFactory2,
|
|
60
|
+
None,
|
|
61
|
+
CLSCTX_INPROC_SERVER,
|
|
62
|
+
IID_IWICImagingFactory2,
|
|
63
|
+
byref(factory))
|
|
64
|
+
return factory
|
|
65
|
+
except OSError:
|
|
66
|
+
pass
|
|
67
|
+
|
|
68
|
+
try:
|
|
69
|
+
factory = IWICImagingFactory()
|
|
70
|
+
ole32.CoCreateInstance(CLSID_WICImagingFactory1,
|
|
71
|
+
None,
|
|
72
|
+
CLSCTX_INPROC_SERVER,
|
|
73
|
+
IID_IWICImagingFactory1,
|
|
74
|
+
byref(factory))
|
|
75
|
+
return factory
|
|
76
|
+
except OSError:
|
|
77
|
+
pass
|
|
78
|
+
|
|
79
|
+
return None
|
|
80
|
+
|
|
81
|
+
_factory = _create_factory()
|
|
82
|
+
if not _factory:
|
|
83
|
+
raise ImportError("Could not create WIC factory.")
|
|
84
|
+
|
|
85
|
+
def get_factory() -> IWICImagingFactory2 | IWICImagingFactory:
|
|
86
|
+
"""Retrieve the current WIC factory.
|
|
87
|
+
|
|
88
|
+
WIC interfaces with many other libraries such as DirectWrite and Direct2D.
|
|
89
|
+
"""
|
|
90
|
+
return _factory
|
|
91
|
+
|
|
92
|
+
def _get_bitmap_frame(bitmap_decoder: IWICBitmapDecoder, frame_index: int) -> IWICBitmapFrameDecode:
|
|
93
|
+
bitmap = IWICBitmapFrameDecode()
|
|
94
|
+
bitmap_decoder.GetFrame(frame_index, byref(bitmap))
|
|
95
|
+
return bitmap
|
|
96
|
+
|
|
97
|
+
def get_bitmap(width: int, height: int, target_fmt: com.GUID=GUID_WICPixelFormat32bppBGRA) -> IWICBitmap:
|
|
98
|
+
"""Create a WIC Bitmap.
|
|
99
|
+
|
|
100
|
+
Caller is responsible for releasing ``IWICBitmap``.
|
|
101
|
+
"""
|
|
102
|
+
bitmap = IWICBitmap()
|
|
103
|
+
_factory.CreateBitmap(width, height,
|
|
104
|
+
target_fmt,
|
|
105
|
+
WICBitmapCacheOnDemand,
|
|
106
|
+
byref(bitmap))
|
|
107
|
+
return bitmap
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def extract_image_data(bitmap: IWICBitmap, target_fmt: com.GUID = GUID_WICPixelFormat32bppBGRA) -> ImageData:
|
|
111
|
+
"""Extra image data from IWICBitmap into ImageData, specifying target format.
|
|
112
|
+
|
|
113
|
+
.. note:: ``bitmap`` is released before this function returns.
|
|
114
|
+
"""
|
|
115
|
+
width = UINT()
|
|
116
|
+
height = UINT()
|
|
117
|
+
|
|
118
|
+
bitmap.GetSize(byref(width), byref(height))
|
|
119
|
+
|
|
120
|
+
width = int(width.value)
|
|
121
|
+
height = int(height.value)
|
|
122
|
+
|
|
123
|
+
# Get image pixel format
|
|
124
|
+
pf = com.GUID(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
|
|
125
|
+
bitmap.GetPixelFormat(byref(pf))
|
|
126
|
+
|
|
127
|
+
fmt = 'BGRA'
|
|
128
|
+
# If target format is not what we want (32bit BGRA) convert it.
|
|
129
|
+
if pf != target_fmt:
|
|
130
|
+
converter = IWICFormatConverter()
|
|
131
|
+
_factory.CreateFormatConverter(byref(converter))
|
|
132
|
+
|
|
133
|
+
conversion_possible = BOOL()
|
|
134
|
+
converter.CanConvert(pf, target_fmt, byref(conversion_possible))
|
|
135
|
+
|
|
136
|
+
# 99% of the time conversion will be possible to default.
|
|
137
|
+
# However, we check to be safe and fallback to 24 bit BGR if not possible.
|
|
138
|
+
if not conversion_possible:
|
|
139
|
+
target_fmt = GUID_WICPixelFormat24bppBGR
|
|
140
|
+
fmt = 'BGR'
|
|
141
|
+
|
|
142
|
+
converter.Initialize(bitmap, target_fmt, WICBitmapDitherTypeNone, None, 0, WICBitmapPaletteTypeCustom)
|
|
143
|
+
|
|
144
|
+
bitmap.Release()
|
|
145
|
+
bitmap = converter
|
|
146
|
+
|
|
147
|
+
# Most images are loaded with a negative pitch, which requires list comprehension to fix.
|
|
148
|
+
# Create a flipped bitmap through the decoder rather through Python to increase performance.
|
|
149
|
+
flipper = IWICBitmapFlipRotator()
|
|
150
|
+
_factory.CreateBitmapFlipRotator(byref(flipper))
|
|
151
|
+
|
|
152
|
+
flipper.Initialize(bitmap, WICBitmapTransformFlipVertical)
|
|
153
|
+
|
|
154
|
+
stride = len(fmt) * width
|
|
155
|
+
buffer_size = stride * height
|
|
156
|
+
|
|
157
|
+
buffer = (BYTE * buffer_size)()
|
|
158
|
+
|
|
159
|
+
flipper.CopyPixels(None, stride, buffer_size, byref(buffer))
|
|
160
|
+
|
|
161
|
+
flipper.Release()
|
|
162
|
+
bitmap.Release() # Can be converter.
|
|
163
|
+
|
|
164
|
+
return ImageData(width, height, fmt, buffer)
|
|
405
165
|
|
|
406
166
|
|
|
407
167
|
class WICDecoder(ImageDecoder):
|
|
408
|
-
"""Windows Imaging Component.
|
|
409
|
-
This decoder is a replacement for GDI and GDI+ starting with Windows 7 with more features up to Windows 10."""
|
|
168
|
+
"""Windows Imaging Component implementation for image decoding.
|
|
410
169
|
|
|
411
|
-
|
|
170
|
+
This decoder is a replacement for GDI/GDI+ starting with Windows 7.
|
|
171
|
+
"""
|
|
172
|
+
def __init__(self) -> None: # noqa: D107
|
|
412
173
|
super(ImageDecoder, self).__init__()
|
|
413
|
-
self._factory =
|
|
174
|
+
self._factory = get_factory()
|
|
414
175
|
|
|
415
|
-
def get_file_extensions(self):
|
|
176
|
+
def get_file_extensions(self) -> Sequence[str]:
|
|
416
177
|
return ['.bmp', '.jpg', '.jpeg', '.png', '.tif', '.tiff', '.ico', '.jxr', '.hdp', '.wdp']
|
|
417
178
|
|
|
418
|
-
def _load_bitmap_decoder(self, filename, file):
|
|
179
|
+
def _load_bitmap_decoder(self, filename: str, file: BinaryIO | None = None) -> tuple[IWICBitmapDecoder, IStream]:
|
|
419
180
|
data = file.read()
|
|
420
181
|
|
|
421
182
|
# Create a HGLOBAL with image data
|
|
@@ -425,7 +186,7 @@ class WICDecoder(ImageDecoder):
|
|
|
425
186
|
kernel32.GlobalUnlock(hglob)
|
|
426
187
|
|
|
427
188
|
# Create IStream for the HGLOBAL
|
|
428
|
-
stream =
|
|
189
|
+
stream = IStream()
|
|
429
190
|
ole32.CreateStreamOnHGlobal(hglob, True, byref(stream))
|
|
430
191
|
|
|
431
192
|
# Load image from stream
|
|
@@ -437,84 +198,31 @@ class WICDecoder(ImageDecoder):
|
|
|
437
198
|
|
|
438
199
|
return decoder, stream
|
|
439
200
|
|
|
440
|
-
def
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
bitmap.GetSize(byref(width), byref(height))
|
|
451
|
-
|
|
452
|
-
width = int(width.value)
|
|
453
|
-
height = int(height.value)
|
|
454
|
-
|
|
455
|
-
# Get image pixel format
|
|
456
|
-
pf = com.GUID(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
|
|
457
|
-
bitmap.GetPixelFormat(byref(pf))
|
|
458
|
-
|
|
459
|
-
fmt = 'BGRA'
|
|
460
|
-
# If target format is not what we want (32bit BGRA) convert it.
|
|
461
|
-
if pf != target_fmt:
|
|
462
|
-
converter = IWICFormatConverter()
|
|
463
|
-
self._factory.CreateFormatConverter(byref(converter))
|
|
464
|
-
|
|
465
|
-
conversion_possible = BOOL()
|
|
466
|
-
converter.CanConvert(pf, target_fmt, byref(conversion_possible))
|
|
467
|
-
|
|
468
|
-
# 99% of the time conversion will be possible to default.
|
|
469
|
-
# However, we check to be safe and fallback to 24 bit BGR if not possible.
|
|
470
|
-
if not conversion_possible:
|
|
471
|
-
target_fmt = GUID_WICPixelFormat24bppBGR
|
|
472
|
-
fmt = 'BGR'
|
|
473
|
-
|
|
474
|
-
converter.Initialize(bitmap, target_fmt, WICBitmapDitherTypeNone, None, 0, WICBitmapPaletteTypeCustom)
|
|
475
|
-
|
|
476
|
-
bitmap.Release()
|
|
477
|
-
bitmap = converter
|
|
478
|
-
|
|
479
|
-
# Most images are loaded with a negative pitch, which requires list comprehension to fix.
|
|
480
|
-
# Create a flipped bitmap through the decoder rather through Python to increase performance.
|
|
481
|
-
flipper = IWICBitmapFlipRotator()
|
|
482
|
-
self._factory.CreateBitmapFlipRotator(byref(flipper))
|
|
483
|
-
|
|
484
|
-
flipper.Initialize(bitmap, WICBitmapTransformFlipVertical)
|
|
485
|
-
|
|
486
|
-
stride = len(fmt) * width
|
|
487
|
-
buffer_size = stride * height
|
|
488
|
-
|
|
489
|
-
buffer = (BYTE * buffer_size)()
|
|
490
|
-
|
|
491
|
-
flipper.CopyPixels(None, stride, buffer_size, byref(buffer))
|
|
492
|
-
|
|
493
|
-
flipper.Release()
|
|
494
|
-
bitmap.Release() # Can be converter.
|
|
495
|
-
|
|
496
|
-
return ImageData(width, height, fmt, buffer)
|
|
201
|
+
def decode(self, filename: str, file: BinaryIO | None) -> ImageData:
|
|
202
|
+
if not file:
|
|
203
|
+
with open(filename, 'rb') as f:
|
|
204
|
+
bitmap_decoder, stream = self._load_bitmap_decoder(filename, f)
|
|
205
|
+
bitmap = _get_bitmap_frame(bitmap_decoder, 0)
|
|
206
|
+
image_data = extract_image_data(bitmap)
|
|
207
|
+
else:
|
|
208
|
+
bitmap_decoder, stream = self._load_bitmap_decoder(filename, file)
|
|
209
|
+
bitmap = _get_bitmap_frame(bitmap_decoder, 0)
|
|
210
|
+
image_data = extract_image_data(bitmap)
|
|
497
211
|
|
|
498
|
-
def _delete_bitmap_decoder(self, bitmap_decoder, stream):
|
|
499
|
-
# Release decoder and stream
|
|
500
212
|
bitmap_decoder.Release()
|
|
501
213
|
stream.Release()
|
|
502
|
-
|
|
503
|
-
def decode(self, filename, file):
|
|
504
|
-
if not file:
|
|
505
|
-
file = open(filename, 'rb')
|
|
506
|
-
bitmap_decoder, stream = self._load_bitmap_decoder(filename, file)
|
|
507
|
-
bitmap = self._get_bitmap_frame(bitmap_decoder, 0)
|
|
508
|
-
image = self.get_image(bitmap)
|
|
509
|
-
self._delete_bitmap_decoder(bitmap_decoder, stream)
|
|
510
|
-
return image
|
|
214
|
+
return image_data
|
|
511
215
|
|
|
512
216
|
@staticmethod
|
|
513
|
-
def get_property_value(reader, metadata_name):
|
|
514
|
-
"""
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
217
|
+
def get_property_value(reader: IWICMetadataQueryReader, metadata_name: str) -> int:
|
|
218
|
+
"""Uses a metadata name and reader to return a single value.
|
|
219
|
+
|
|
220
|
+
Can be used to get metadata from images.
|
|
221
|
+
|
|
222
|
+
Handles cleanup of PROPVARIANT.
|
|
223
|
+
|
|
224
|
+
Returns:
|
|
225
|
+
0 on failure.
|
|
518
226
|
"""
|
|
519
227
|
try:
|
|
520
228
|
prop = PROPVARIANT()
|
|
@@ -527,7 +235,7 @@ class WICDecoder(ImageDecoder):
|
|
|
527
235
|
return value
|
|
528
236
|
|
|
529
237
|
|
|
530
|
-
def get_decoders():
|
|
238
|
+
def get_decoders() -> Sequence[ImageDecoder]: # noqa: D103
|
|
531
239
|
return [WICDecoder()]
|
|
532
240
|
|
|
533
241
|
|
|
@@ -544,11 +252,11 @@ extension_to_container = {
|
|
|
544
252
|
}
|
|
545
253
|
|
|
546
254
|
|
|
547
|
-
class WICEncoder(ImageEncoder):
|
|
548
|
-
def get_file_extensions(self):
|
|
549
|
-
return
|
|
255
|
+
class WICEncoder(ImageEncoder): # noqa: D101
|
|
256
|
+
def get_file_extensions(self) -> Sequence[str]:
|
|
257
|
+
return list(extension_to_container)
|
|
550
258
|
|
|
551
|
-
def encode(self, image, filename, file):
|
|
259
|
+
def encode(self, image: ImageData, filename: str, file: BinaryIO | None) -> None:
|
|
552
260
|
image = image.get_image_data()
|
|
553
261
|
|
|
554
262
|
wicstream = IWICStream()
|
|
@@ -587,6 +295,7 @@ class WICEncoder(ImageEncoder):
|
|
|
587
295
|
ole32.CreateStreamOnHGlobal(None, True, byref(istream))
|
|
588
296
|
wicstream.InitializeFromIStream(istream)
|
|
589
297
|
else:
|
|
298
|
+
istream = None
|
|
590
299
|
wicstream.InitializeFromFilename(filename, GENERIC_WRITE)
|
|
591
300
|
|
|
592
301
|
_factory.CreateEncoder(container, None, byref(encoder))
|
|
@@ -609,7 +318,7 @@ class WICEncoder(ImageEncoder):
|
|
|
609
318
|
|
|
610
319
|
encoder.Commit()
|
|
611
320
|
|
|
612
|
-
if file:
|
|
321
|
+
if file and istream:
|
|
613
322
|
sts = STATSTG()
|
|
614
323
|
istream.Stat(byref(sts), 0)
|
|
615
324
|
stream_size = sts.cbSize
|
|
@@ -632,5 +341,5 @@ class WICEncoder(ImageEncoder):
|
|
|
632
341
|
wicstream.Release()
|
|
633
342
|
|
|
634
343
|
|
|
635
|
-
def get_encoders():
|
|
344
|
+
def get_encoders() -> Sequence[ImageEncoder]: # noqa: D103
|
|
636
345
|
return [WICEncoder()]
|