1515from __future__ import annotations
1616
1717import sys
18-
19- # mode descriptor cache
20- _modes = None
18+ from functools import lru_cache
2119
2220
2321class ModeDescriptor :
@@ -41,58 +39,58 @@ def __str__(self) -> str:
4139 return self .mode
4240
4341
42+ @lru_cache
4443def getmode (mode : str ) -> ModeDescriptor :
4544 """Gets a mode descriptor for the given mode."""
46- global _modes
47- if not _modes :
48- # initialize mode cache
49- modes = {}
50- endian = "<" if sys .byteorder == "little" else ">"
51- for m , (basemode , basetype , bands , typestr ) in {
52- # core modes
53- # Bits need to be extended to bytes
54- "1" : ("L" , "L" , ("1" ,), "|b1" ),
55- "L" : ("L" , "L" , ("L" ,), "|u1" ),
56- "I" : ("L" , "I" , ("I" ,), endian + "i4" ),
57- "F" : ("L" , "F" , ("F" ,), endian + "f4" ),
58- "P" : ("P" , "L" , ("P" ,), "|u1" ),
59- "RGB" : ("RGB" , "L" , ("R" , "G" , "B" ), "|u1" ),
60- "RGBX" : ("RGB" , "L" , ("R" , "G" , "B" , "X" ), "|u1" ),
61- "RGBA" : ("RGB" , "L" , ("R" , "G" , "B" , "A" ), "|u1" ),
62- "CMYK" : ("RGB" , "L" , ("C" , "M" , "Y" , "K" ), "|u1" ),
63- "YCbCr" : ("RGB" , "L" , ("Y" , "Cb" , "Cr" ), "|u1" ),
64- # UNDONE - unsigned |u1i1i1
65- "LAB" : ("RGB" , "L" , ("L" , "A" , "B" ), "|u1" ),
66- "HSV" : ("RGB" , "L" , ("H" , "S" , "V" ), "|u1" ),
67- # extra experimental modes
68- "RGBa" : ("RGB" , "L" , ("R" , "G" , "B" , "a" ), "|u1" ),
69- "BGR;15" : ("RGB" , "L" , ("B" , "G" , "R" ), "|u1" ),
70- "BGR;16" : ("RGB" , "L" , ("B" , "G" , "R" ), "|u1" ),
71- "BGR;24" : ("RGB" , "L" , ("B" , "G" , "R" ), "|u1" ),
72- "LA" : ("L" , "L" , ("L" , "A" ), "|u1" ),
73- "La" : ("L" , "L" , ("L" , "a" ), "|u1" ),
74- "PA" : ("RGB" , "L" , ("P" , "A" ), "|u1" ),
75- }.items ():
76- modes [m ] = ModeDescriptor (m , bands , basemode , basetype , typestr )
77- # mapping modes
78- for i16mode , typestr in {
79- # I;16 == I;16L, and I;32 == I;32L
80- "I;16" : "<u2" ,
81- "I;16S" : "<i2" ,
82- "I;16L" : "<u2" ,
83- "I;16LS" : "<i2" ,
84- "I;16B" : ">u2" ,
85- "I;16BS" : ">i2" ,
86- "I;16N" : endian + "u2" ,
87- "I;16NS" : endian + "i2" ,
88- "I;32" : "<u4" ,
89- "I;32B" : ">u4" ,
90- "I;32L" : "<u4" ,
91- "I;32S" : "<i4" ,
92- "I;32BS" : ">i4" ,
93- "I;32LS" : "<i4" ,
94- }.items ():
95- modes [i16mode ] = ModeDescriptor (i16mode , ("I" ,), "L" , "L" , typestr )
96- # set global mode cache atomically
97- _modes = modes
98- return _modes [mode ]
45+ # initialize mode cache
46+ endian = "<" if sys .byteorder == "little" else ">"
47+
48+ modes = {
49+ # core modes
50+ # Bits need to be extended to bytes
51+ "1" : ("L" , "L" , ("1" ,), "|b1" ),
52+ "L" : ("L" , "L" , ("L" ,), "|u1" ),
53+ "I" : ("L" , "I" , ("I" ,), endian + "i4" ),
54+ "F" : ("L" , "F" , ("F" ,), endian + "f4" ),
55+ "P" : ("P" , "L" , ("P" ,), "|u1" ),
56+ "RGB" : ("RGB" , "L" , ("R" , "G" , "B" ), "|u1" ),
57+ "RGBX" : ("RGB" , "L" , ("R" , "G" , "B" , "X" ), "|u1" ),
58+ "RGBA" : ("RGB" , "L" , ("R" , "G" , "B" , "A" ), "|u1" ),
59+ "CMYK" : ("RGB" , "L" , ("C" , "M" , "Y" , "K" ), "|u1" ),
60+ "YCbCr" : ("RGB" , "L" , ("Y" , "Cb" , "Cr" ), "|u1" ),
61+ # UNDONE - unsigned |u1i1i1
62+ "LAB" : ("RGB" , "L" , ("L" , "A" , "B" ), "|u1" ),
63+ "HSV" : ("RGB" , "L" , ("H" , "S" , "V" ), "|u1" ),
64+ # extra experimental modes
65+ "RGBa" : ("RGB" , "L" , ("R" , "G" , "B" , "a" ), "|u1" ),
66+ "BGR;15" : ("RGB" , "L" , ("B" , "G" , "R" ), "|u1" ),
67+ "BGR;16" : ("RGB" , "L" , ("B" , "G" , "R" ), "|u1" ),
68+ "BGR;24" : ("RGB" , "L" , ("B" , "G" , "R" ), "|u1" ),
69+ "LA" : ("L" , "L" , ("L" , "A" ), "|u1" ),
70+ "La" : ("L" , "L" , ("L" , "a" ), "|u1" ),
71+ "PA" : ("RGB" , "L" , ("P" , "A" ), "|u1" ),
72+ }
73+ if mode in modes :
74+ base_mode , base_type , bands , type_str = modes [mode ]
75+ return ModeDescriptor (mode , bands , base_mode , base_type , type_str )
76+
77+ mapping_modes = {
78+ # I;16 == I;16L, and I;32 == I;32L
79+ "I;16" : "<u2" ,
80+ "I;16S" : "<i2" ,
81+ "I;16L" : "<u2" ,
82+ "I;16LS" : "<i2" ,
83+ "I;16B" : ">u2" ,
84+ "I;16BS" : ">i2" ,
85+ "I;16N" : endian + "u2" ,
86+ "I;16NS" : endian + "i2" ,
87+ "I;32" : "<u4" ,
88+ "I;32B" : ">u4" ,
89+ "I;32L" : "<u4" ,
90+ "I;32S" : "<i4" ,
91+ "I;32BS" : ">i4" ,
92+ "I;32LS" : "<i4" ,
93+ }
94+
95+ type_str = mapping_modes [mode ]
96+ return ModeDescriptor (mode , ("I" ,), "L" , "L" , type_str )
0 commit comments