@@ -34,10 +34,6 @@ def _i(c: bytes) -> int:
34
34
return i32 ((b"\0 \0 \0 \0 " + c )[- 4 :])
35
35
36
36
37
- def _i8 (c : int | bytes ) -> int :
38
- return c if isinstance (c , int ) else c [0 ]
39
-
40
-
41
37
##
42
38
# Image plugin for IPTC/NAA datastreams. To read IPTC/NAA fields
43
39
# from TIFF and JPEG files, use the <b>getiptcinfo</b> function.
@@ -100,16 +96,18 @@ def _open(self) -> None:
100
96
# mode
101
97
layers = self .info [(3 , 60 )][0 ]
102
98
component = self .info [(3 , 60 )][1 ]
103
- if (3 , 65 ) in self .info :
104
- id = self .info [(3 , 65 )][0 ] - 1
105
- else :
106
- id = 0
107
99
if layers == 1 and not component :
108
100
self ._mode = "L"
109
- elif layers == 3 and component :
110
- self ._mode = "RGB" [id ]
111
- elif layers == 4 and component :
112
- self ._mode = "CMYK" [id ]
101
+ band = None
102
+ else :
103
+ if layers == 3 and component :
104
+ self ._mode = "RGB"
105
+ elif layers == 4 and component :
106
+ self ._mode = "CMYK"
107
+ if (3 , 65 ) in self .info :
108
+ band = self .info [(3 , 65 )][0 ] - 1
109
+ else :
110
+ band = 0
113
111
114
112
# size
115
113
self ._size = self .getint ((3 , 20 )), self .getint ((3 , 30 ))
@@ -124,39 +122,44 @@ def _open(self) -> None:
124
122
# tile
125
123
if tag == (8 , 10 ):
126
124
self .tile = [
127
- ImageFile ._Tile ("iptc" , (0 , 0 ) + self .size , offset , compression )
125
+ ImageFile ._Tile ("iptc" , (0 , 0 ) + self .size , offset , ( compression , band ) )
128
126
]
129
127
130
128
def load (self ) -> Image .core .PixelAccess | None :
131
- if len (self .tile ) != 1 or self .tile [0 ][0 ] != "iptc" :
132
- return ImageFile .ImageFile .load (self )
133
-
134
- offset , compression = self .tile [0 ][2 :]
135
-
136
- self .fp .seek (offset )
137
-
138
- # Copy image data to temporary file
139
- o = BytesIO ()
140
- if compression == "raw" :
141
- # To simplify access to the extracted file,
142
- # prepend a PPM header
143
- o .write (b"P5\n %d %d\n 255\n " % self .size )
144
- while True :
145
- type , size = self .field ()
146
- if type != (8 , 10 ):
147
- break
148
- while size > 0 :
149
- s = self .fp .read (min (size , 8192 ))
150
- if not s :
129
+ if self .tile :
130
+ args = self .tile [0 ].args
131
+ assert isinstance (args , tuple )
132
+ compression , band = args
133
+
134
+ self .fp .seek (self .tile [0 ].offset )
135
+
136
+ # Copy image data to temporary file
137
+ o = BytesIO ()
138
+ if compression == "raw" :
139
+ # To simplify access to the extracted file,
140
+ # prepend a PPM header
141
+ o .write (b"P5\n %d %d\n 255\n " % self .size )
142
+ while True :
143
+ type , size = self .field ()
144
+ if type != (8 , 10 ):
151
145
break
152
- o .write (s )
153
- size -= len (s )
154
-
155
- with Image .open (o ) as _im :
156
- _im .load ()
157
- self .im = _im .im
158
- self .tile = []
159
- return Image .Image .load (self )
146
+ while size > 0 :
147
+ s = self .fp .read (min (size , 8192 ))
148
+ if not s :
149
+ break
150
+ o .write (s )
151
+ size -= len (s )
152
+
153
+ with Image .open (o ) as _im :
154
+ if band is not None :
155
+ bands = [Image .new ("L" , _im .size )] * Image .getmodebands (self .mode )
156
+ bands [band ] = _im
157
+ _im = Image .merge (self .mode , bands )
158
+ else :
159
+ _im .load ()
160
+ self .im = _im .im
161
+ self .tile = []
162
+ return ImageFile .ImageFile .load (self )
160
163
161
164
162
165
Image .register_open (IptcImageFile .format , IptcImageFile )
0 commit comments