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,59 @@ 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+ # if not _modes:
46+ # initialize mode cache
47+ endian = "<" if sys . byteorder == "little" else ">"
48+
49+ modes = {
50+ # core modes
51+ # Bits need to be extended to bytes
52+ "1" : ( "L" , "L" , ( "1" ,), "|b1" ),
53+ "L " : ("L" , "L" , ("L " ,), "|u1 " ),
54+ "I " : ("L" , "I " , ("I " ,), endian + "i4 " ),
55+ "F " : ("L" , "F " , ("F " ,), endian + "f4 " ),
56+ "P " : ("P " , "L " , ("P " ,), "|u1 " ),
57+ "RGB " : ("RGB " , "L" , ("R" , "G" , "B" ), "|u1" ),
58+ "RGBX " : ("RGB" , "L" , ("R" , "G" , "B" , "X " ), "|u1" ),
59+ "RGBA " : ("RGB" , "L" , ("R" , "G" , "B" , "A " ), "|u1" ),
60+ "CMYK " : ("RGB" , "L" , ("C " , "M " , "Y " , "K " ), "|u1" ),
61+ "YCbCr " : ("RGB" , "L" , ("Y " , "Cb " , "Cr " ), "|u1" ),
62+ # UNDONE - unsigned |u1i1i1
63+ "LAB" : ( "RGB" , "L" , ( "L" , "A" , "B" ), "|u1" ),
64+ "HSV " : ("RGB" , "L" , ("H " , "S " , "V " ), "|u1" ),
65+ # extra experimental modes
66+ "RGBa" : ( "RGB" , "L" , ( "R" , "G" , "B" , "a" ), "|u1" ),
67+ "BGR;15 " : ("RGB" , "L" , ("B " , "G" , "R " ), "|u1" ),
68+ "BGR;16 " : ("RGB" , "L" , ("B" , "G" , "R" ), "|u1" ),
69+ "BGR;24 " : ("RGB" , "L" , ("B" , "G" , "R" ), "|u1" ),
70+ "LA " : ("L " , "L" , ("L " , "A " ), "|u1" ),
71+ "La " : ("L" , "L" , ("L" , "a " ), "|u1" ),
72+ "PA " : ("RGB " , "L" , ("P " , "A " ), "|u1" ),
73+ }
74+ if mode in modes :
75+ base_mode , base_type , bands , type_str = modes [ mode ]
76+ return ModeDescriptor ( mode , bands , base_mode , base_type , type_str )
77+
78+ mapping_modes = {
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+ }
95+
96+ type_str = mapping_modes [ mode ]
97+ return ModeDescriptor ( mode , ( "I" ,), "L" , "L" , type_str )
0 commit comments