@@ -34,10 +34,6 @@ def _i(c: bytes) -> int:
3434 return i32 ((b"\0 \0 \0 \0 " + c )[- 4 :])
3535
3636
37- def _i8 (c : int | bytes ) -> int :
38- return c if isinstance (c , int ) else c [0 ]
39-
40-
4137##
4238# Image plugin for IPTC/NAA datastreams. To read IPTC/NAA fields
4339# from TIFF and JPEG files, use the <b>getiptcinfo</b> function.
@@ -100,16 +96,18 @@ def _open(self) -> None:
10096 # mode
10197 layers = self .info [(3 , 60 )][0 ]
10298 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
10799 if layers == 1 and not component :
108100 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
113111
114112 # size
115113 self ._size = self .getint ((3 , 20 )), self .getint ((3 , 30 ))
@@ -124,39 +122,44 @@ def _open(self) -> None:
124122 # tile
125123 if tag == (8 , 10 ):
126124 self .tile = [
127- ImageFile ._Tile ("iptc" , (0 , 0 ) + self .size , offset , compression )
125+ ImageFile ._Tile ("iptc" , (0 , 0 ) + self .size , offset , ( compression , band ) )
128126 ]
129127
130128 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 ):
151145 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 )
160163
161164
162165Image .register_open (IptcImageFile .format , IptcImageFile )
0 commit comments