a :jg@@s ddlmZddlZddlZddlZddlZddlZddlZddlZddl m Z m Z ddl m Z ddlmZmZddlmZmZmZmZmZmZddlmZmZmZmZmZmZdd lm Z!dd lm"Z#dd lm$Z$dd l%m&Z&dd l'm(Z(ddl)m*Z*ddlm+Z+erddl'm,Z,m-Z-e.e/Z0dZ1dZ2dZ3dZ4dZ5dZ6dZ7dZ8dZ9dZ:dZ;dZdZ?dZ@d ZAd!ZBd"ZCd#ZDd$ZEd%ZFd&ZGd'ZHd(ZId)ZJd*ZKd+ZLd,ZMd-ZNd.ZOd/ZPd0ZQd1ZRd2ZSd3ZTd4ZUd5ZVd6ZWd7ZXd8ZYd9ZZd:Z[d;Z\dd?d@dAdBdCdDdEdFdGdHdIdJdKdLdMdNdOZ_dPdQe_`DZae4ddRddRdSfdTe5ddRddRdSfdTe4ddRdUdRdSfdVe5ddRdUdRdSfdVe4ddRddRdSfdWe5ddRddRdSfdWe4ddRdUdRdSfdXe5ddRdUdRdSfdXe4ddRddYdSfdZe5ddRddYdSfdZe4ddRdUdYdSfd[e5ddRdUdYdSfd[e4ddRddYdSfd\e5ddRddYdSfd\e4ddRdUdYdSfd]e5ddRdUdYdSfd]e4ddRdd^dSfd_e5ddRdd^dSfd_e4ddRdUd^dSfd`e5ddRdUd^dSfd`e4ddRdd^dSfdae5ddRdd^dSfdae4ddRdUd^dSfdbe5ddRdUd^dSfdbe4ddRddcdSfdde5ddRddcdSfdde4ddRdUdcdSfdee5ddRdUdcdSfdee4ddRddcdSfdfe5ddRddcdSfdfe4ddYddcdSfdfe5ddYddcdSfdfe4ddRdUdcdSfdge5ddRdUdcdSfdge4ddRddhdSfdie4ddRddjdSfdke4ddRddjdSfdke5ddRddjdSfdle4ddRdUdjdSfdme4ddYddjdSfdne5ddYddjdSfdoe4ddpddqdSfdre5ddpddqdSfdse4ddRddqdSfdte4ddYddqdSfdue5ddYddqdSfdve4ddpddqdSfdre5ddpddqdSfdse4ddRddwdYfdxe5ddRddwdYfdxe4dUdRddydSfdze5dUdRddydSfdze4dUdRdUdydSfd{e5dUdRdUdydSfd{e4dUdRdd|dSfd}e5dUdRdd|dSfd}e4dUdRdd|d~fde5dUdRdd|d~fde4dUdRdddfde5dUdRdddfde4dUdRdddfde5dUdRdddfde4dUdRdd|dRfde5dUdRdd|dRfde4dUdRdddfde5dUdRdddfde4dUdRdddfde5dUdRdddfde4dUdRdd|dYfd}e5dUdRdd|dYfd}e4dUdRdddfde5dUdRdddfde4dUdRdddfde5dUdRdddfde4dUdRdd|dfd}e5dUdRdd|dfd}e4dUdRdddSfde5dUdRdddSfde4dUdRdddSfde5dUdRdddSfde4dUdRddd~fde5dUdRddd~fde4dUdRdddRfde5dUdRdddRfde4dUdRdddYfde5dUdRdddYfde4ddRddRdSfde5ddRddRdSfde4ddRdUdRdSfde5ddRdUdRdSfde4ddRddYdSfde5ddRddYdSfde4ddRdUdYdSfde5ddRdUdYdSfde4ddRdd^dSfde5ddRdd^dSfde4ddRdUd^dSfde5ddRdUd^dSfde4ddRddcdSfde5ddRddcdSfde4ddRddwd~fde4ddRddwdYfde5ddRddwdYfde4ddRdUdcdSfde5ddRdUdcdSfde4ddRdd|dSfde5ddRdd|dSfde4ddRddd~fde5ddRddd~fde4ddRdddfde5ddRdddfde4ddRdddSfde5ddRdddSfde4ddRddcdSfdfe5ddRddcdSfdfe4ddRddydSfde5ddRddydSfde4ddRddydSfde5ddRddydSfdiwZbecddebDZdgdZeefejgdd se&dddddddZhddddddZidddddddÄZjiZkiZldddƜddȄZmGdddeZnedeoepgefZqdddd̜dd΄ZrdddМdd҄Zsddd՜ddׄZte rte euefZvne ZvGddʄdevZwekew_kelew_le+`D]F\ZxZyeyzddڡZye{ewdeyekexde{ewdeyelex q[k[l[x[yGddބdewZ|e|Z}GdddejZ~de4dddRdfde4dddcdfde4dddwdUfde4dddcdfde4dddwdUfde4ddUdqdfde4dddjdfde4ddUdjdfde4dddqdfde4dUddydfde4dUdd|dfde4dUdd|dUfde4ddd|dfde4dddydfde4dddydfde5ddUdqdfde5dddjdfde5ddUdjdfde5dddqdfdZdddddddZGdddejZdddddddZee~je~ehee~jeee~jeee~jddgee~jddS() annotationsN)IteratorMutableMapping)Fraction)NumberRational)IO TYPE_CHECKINGAnyCallableNoReturncast)ExifTagsImage ImageFileImageOps ImagePaletteTiffTags)i16be)i32beo8) deprecate)StrOrBytesPath)is_pathTYPES)Buffer IntegralLikeFsIIsMMiiiii iiiiiiii(i-i1i2i;i=i@iBiCDiEiJiRiSi[iiiiiIisiiiiiirawZ tiff_ccittZgroup3Zgroup4Ztiff_lzw tiff_jpegjpegtiff_adobe_deflateZ tiff_raw_16ZpackbitsZtiff_thunderscan tiff_deflateZ tiff_sgilogZ tiff_sgilog24lzmaZzstdZwebp)riii)iitiuimiPiQcCsi|]\}}||qSr2).0kvr2r2=/usr/local/lib/python3.9/site-packages/PIL/TiffImagePlugin.py r7rr2)1z1;Ir+)r:z1;IR)r:r:)r:z1;R)r+)LzL;2I)r;zL;2IR)r;zL;2)r;zL;2R)r-)r;zL;4I)r;zL;4IR)r;zL;4)r;zL;4R)r1)r;zL;I)r;zL;IR)r;r;)r;zL;R) )I;16zI;12))r=r=)I;16Br?)r=zI;16R)II;16S)r@I;16BS)r,) )FF;32F)rDF;32BF)r@zI;32N)r@I;32S)r@I;32BS)r1r1)LArI)r1r1r1)RGBrJ)rJzRGB;R)r1r1r1r1)RGBArK)r)rJRGBX)r1r1r1r1r1rr)rJZRGBXX)r1r1r1r1r1r1)rrr)rJZRGBXXX)rKZRGBa)rr)rKZRGBaX)rrr)rKZRGBaXX)r+r)rKZRGBAX)r+rr)rKZRGBAXX)i)r>r>r>)rJzRGB;16L)rJzRGB;16B)r>r>r>r>)rKzRGBA;16L)rKzRGBA;16B)rJzRGBX;16L)rJzRGBX;16B)rKzRGBa;16L)rKzRGBa;16Br,)PzP;1)rNzP;1R)rNzP;2)rNzP;2R)rNzP;4)rNzP;4R)rNrN)rNZPX)PArO)rNzP;Rr.)CMYKrP)rPZCMYKX)rPZCMYKXX)rPzCMYK;16L)rPzCMYK;16Br/r1)LABrQccs|]}t|dVqdS)r-N)len)r3Zkey_tpr2r2r6 r8rS)MM*II*sMM*sII*sMM+sII+libtiff_support_custom_tagsTz*Support for LibTIFF earlier than version 4r<bytesbool)prefixreturncCs|ddtvSNr-)PREFIXESrYr2r2r6_accept"sr^float | Fraction | IFDRationalintz!tuple[IntegralLike, IntegralLike])valmax_valrZcCs@tt|dk}t|rd|n||}|r<|dddS|S)Nr)absfloat IFDRationallimit_rational)rarbinvn_dr2r2r6_limit_rational&srjrf)rarbmin_valrZcCspt|}|j|jf}tdd|D|kr8t|t|}tdd|D}t||krlt|d|d|}|S)Ncss|]}t|VqdSNrer3ir2r2r6rS4r8z)_limit_signed_rational..css|]}t|VqdSrlrmrnr2r2r6rS7r8rr)r numerator denominatorminrjrdtuplemax)rarbrkfracriZ n_d_floatr2r2r6_limit_signed_rational.s  rvstrr )oprZcsddddfdd }|S)Nrfztuple[float, ...]zbool | float | Fraction)selfargsrZcst|j|Srl)getattr_valryrzrxr2r6delegateFsz_delegate..delegater2)rxrr2r~r6 _delegateEsrc@seZdZdZdZd@dddddd Zed d d d Zedd ddZdddddZ dd ddZ dd ddZ dddddZ dd dd Z ddd!d"d#Zed$Zed%Zed&Zed'Zed(Zed)Zed*Zed+Zed,Zed-Zed.Zed/Zed0Zed1Zed2Zed3Zed4Z ed5Z!ed6Z"ed7Z#ed8Z$ed9Z%ed:Z&ed;Z'ed<Z(ed=Z)e*e+d>red>Z,d?S)ArfzImplements a rational class where 0/0 is a legal value to match the in the wild use of exif rationals. e.g., DigitalZoomRatio - 0.00/0.00 indicates that no digital zoom was used ) _numerator _denominatorr|rr_r`None)valuerqrZcCs|t|tr*|j|_|j|_|j|_dSt|trF|j|_|j|_ntrXt t ||_n||_||_|dkrxt d|_n@|dkrt||_n,t ||krtt |||_nt|||_dS)z :param value: either an integer numerator, a float/rational/other number, or an IFDRational :param denominator: Optional integer denominator Nrnanr) isinstancerfrprrqrr|rr r rrer`)ryrrqr2r2r6__init__\s(      zIFDRational.__init__rrZcCs|jSrl)rryr2r2r6rp~szIFDRational.numeratorcCs|jSrl)rrr2r2r6rqszIFDRational.denominatorztuple[IntegralLike, int])max_denominatorrZcCs>|jdkr|j|jfSt|jts&J|j|}|j|jfS)z :param max_denominator: Integer, the maximum denominator value :returns: Tuple of (numerator, denominator) r)rqrprr|rlimit_denominator)ryrfr2r2r6rgs    zIFDRational.limit_rationalrwcCstt|jSrl)rwrer|rr2r2r6__repr__szIFDRational.__repr__cCs |jSrl)r|__hash__rr2r2r6rszIFDRational.__hash__objectrX)otherrZcCs0|j}t|tr|j}t|tr(t|}||kSrl)r|rrfre)ryrrar2r2r6__eq__s   zIFDRational.__eq__z%list[float | Fraction | IntegralLike]cCs|j|j|jgSrl)r|rrrr2r2r6 __getstate__szIFDRational.__getstate__)staterZcCs^t|d|\}}}t|ttfs(J||_tr@tt||_ n||_ t|t sTJ||_ dS)Nr) rfrrrerr|r r rrr`r)ryrr|rrr2r2r6 __setstate__s  zIFDRational.__setstate____add____radd____sub____rsub____mul____rmul__ __truediv__ __rtruediv__ __floordiv__ __rfloordiv____mod____rmod____pow____rpow____pos____neg____abs__ __trunc____lt____gt____le____ge____bool____ceil__ __floor__ __round____int__N)r)-__name__ __module__ __qualname____doc__ __slots__rpropertyrprqrgrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrhasattrrrr2r2r2r6rfNsT " ImageFileDirectory_v2z$Callable[[_LoaderFunc], _LoaderFunc])idxsizerZcsdddfdd }|S)N _LoaderFuncfuncrZcsBddlm}|jdr2|jdddd|<|ft<|S)Nrrload_r._ )rrr startswithreplace_load_dispatch)rrrrr2r6 decorators    z#_register_loader..decoratorr2)rrrr2rr6_register_loadersrz2Callable[[Callable[..., Any]], Callable[..., Any]])rrZcsdddfdd }|S)NzCallable[..., Any]rcs |t<|Srl)_write_dispatch)rrr2r6rsz#_register_writer..decoratorr2)rrr2rr6_register_writersrztuple[int, str, str]r) idx_fmt_namerZcsjddlm}|\}}|||<tddddddd fd d }|ft|<fd d t|<dS)Nrr=TrrWrXtuple[Any, ...])rydata legacy_apirZcs|t||Srl)_unpackrRryrrfmtrr2r6 basic_handlersz&_register_basic..basic_handlercsdfdd|DS)Nr8c3s|]}|VqdSrl)_packr3r)rryr2r6rSr8z4_register_basic....joinryvalues)rrr6sz!_register_basic..)T)rrstructcalcsizerr)rrrnamerr2rr6_register_basics   rc@seZdZUdZiZded<iZded<d|dd d d d d dZeddZ eddZ eddddZ e j dddddZ d dddZ ddddZdddd Zd!dd"d#Zd!d$d%d&d'Zd(dd%d)d*Zd!d$d d+d,d-Zd!d$dd d.d/d0Zd!d d%d1d2Zd3dd4d5Zddd6d7d8d9Zdd$dd:d;d<Zeeeejd=d>fejd?d@fejdAdBfej dCdDfej!dEdFfej"dGdHfej#dIdJfej$d?d@fej%dKdLfg e&dMdMd}ddddOdPdQZ'e(dMdRddSdTdUZ)e&dVdMd~ddddOdWdXZ*e(dVdYdddZd[Z+e&d\d]dddd^dOd_d`Z,e(d\daddbdcddZ-e&dedMdddddOdfdgZ.e(dedRdddhdiZ/e&djd]dddd^dOdkdlZ0e(djdaddbdmdnZ1dod!ddpdqdrZ2dod dsdtduZ3dd!ddwdxdyZ4dod!dsdzd{Z5dS)raThis class represents a TIFF tag directory. To speed things up, we don't decode tags unless they're asked for. Exposes a dictionary interface of the tags in the directory:: ifd = ImageFileDirectory_v2() ifd[key] = 'Some Data' ifd.tagtype[key] = TiffTags.ASCII print(ifd[key]) 'Some Data' Individual values are returned as the strings or numbers, sequences are returned as tuples of the values. The tiff metadata type of each item is stored in a dictionary of tag types in :attr:`~PIL.TiffImagePlugin.ImageFileDirectory_v2.tagtype`. The types are read from a tiff file, guessed from the type added, or added manually. Data Structures: * ``self.tagtype = {}`` * Key: numerical TIFF tag number * Value: integer corresponding to the data type from :py:data:`.TiffTags.TYPES` .. versionadded:: 3.0.0 'Internal' data structures: * ``self._tags_v2 = {}`` * Key: numerical TIFF tag number * Value: decoded data, as tuple for multiple values * ``self._tagdata = {}`` * Key: numerical TIFF tag number * Value: undecoded byte string from file * ``self._tags_v1 = {}`` * Key: numerical TIFF tag number * Value: decoded data in the v1 format Tags will be found in the private attributes ``self._tagdata``, and in ``self._tags_v2`` once decoded. ``self.legacy_api`` is a value for internal use, and shouldn't be changed from outside code. In cooperation with :py:class:`~PIL.TiffImagePlugin.ImageFileDirectory_v1`, if ``legacy_api`` is true, then decoded tags will be populated into both ``_tags_v1`` and ``_tags_v2``. ``_tags_v2`` will be used if this IFD is used in the TIFF save routine. Tags should be read from ``_tags_v1`` if ``legacy_api == true``. z"dict[int, tuple[int, _LoaderFunc]]rzdict[int, Callable[..., Any]]rII*NrWz bytes | None int | Noner)ifhrYgrouprZcCst|s dt|d}t||dur,|n |dd|_|jtkrLd|_n|jtkr^d|_n d}t||ddk|_||_i|_ | |jr| d |d dd n| d |d dd |_ d|_ dS)aInitialize an ImageFileDirectory. To construct an ImageFileDirectory from a real file, pass the 8-byte magic header to the constructor. To only set the endianness, pass it as the 'prefix' keyword argument. :param ifh: One of the accepted magic headers (cf. PREFIXES); also sets endianness. :param prefix: Override the endianness of the file. znot a TIFF file (header z not valid)Nr+>cCs|jSrl)_offsetrr2r2r6ror8rXrcCs|jSrl)rrr2r2r6rqsz ImageFileDirectory_v2.legacy_apir rrZcCsd}t|dS)Nz"Not allowing setting of legacy api) Exception)ryrrr2r2r6ruscCs(i|_i|_i|_i|_d|_d|_dSrl)_tags_v1_tags_v2_tagdatar_nextrrr2r2r6rzs zImageFileDirectory_v2.resetrwcCs tt|Srl)rwdictrr2r2r6__str__szImageFileDirectory_v2.__str__zdict[str, Any]csfddDS)z :returns: dict of name|key: value Returns the complete tag dictionary, with named tags where possible. cs"i|]\}}t|jj|qSr2)rlookuprr)r3coderrr2r6r7sz/ImageFileDirectory_v2.named..)itemsrr2rr6nameds zImageFileDirectory_v2.namedr`cCstt|jt|jBSrl)rRsetrrrr2r2r6__len__szImageFileDirectory_v2.__len__r tagrZcCsf||jvr>|j|}|j|}|j|\}}||||j||<|j|}|jrbt|ttfsb|f}|Srl)rrrrrrrsrW)ryrrtyprhandlerrar2r2r6 __getitem__s    z!ImageFileDirectory_v2.__getitem__rcCs||jvp||jvSrl)rrryrr2r2r6 __contains__sz"ImageFileDirectory_v2.__contains__rrrZcCs||||jdSrl)_setitemr)ryrrr2r2r6 __setitem__sz!ImageFileDirectory_v2.__setitem__)rrrrZc stttf}t||jt||r(|gn|}||jvrpjrNj|j|<n"tj |j|<t dd|Drt dd|Drtj ntj |j|<nt dd|Dr t dd|Drtj |j|<nDt dd|Drtj|j|<n$t dd|Drtjntj|j|<ndt dd|Dr.tj|j|<nBt d d|DrPtj|j|<n t d d|Drptj|j|<|j|tj krd d |D}n |j|tj krd d |D}|j|tjkot|t}|stfdd|D}|r|jn|j}|sjdks@|j|tjks@jdurt|dkr|s|rd|j|tj tj fvrd|f}z|\||<Wn<tytd|dt|d|d||<Yn0n|||<dS)Ncss|]}t|tVqdSrl)rrfr3r5r2r2r6rSr8z1ImageFileDirectory_v2._setitem..css|]}|dkVqdSrNr2r r2r2r6rSr8css|]}t|tVqdSrl)rr`r r2r2r6rSr8css&|]}d|kodknVqdS)rr Nr2r r2r2r6rSr8css&|]}d|kodknVqdS)iiNr2r r2r2r6rSr8css|]}|dkVqdSr r2r r2r2r6rSr8css|]}t|tVqdSrl)rrer r2r2r6rSr8css|]}t|tVqdSrl)rrwr r2r2r6rSr8css|]}t|tVqdSrl)rrWr r2r2r6rSr8cSs&g|]}t|tr|ddn|qS)asciir)rrwencoder r2r2r6 sz2ImageFileDirectory_v2._setitem..cSs"g|]}t|trt|n|qSr2)rr`rer r2r2r6rr8c3s|]}|VqdSrl)Zcvt_enumrinfor2r6rSr8rzMetadata Warning, tag z had too many entries: z , expected 1r)rrWrwrrrrrtype UNDEFINEDallZRATIONALZSIGNED_RATIONALSHORT SIGNED_SHORTLONG SIGNED_LONGDOUBLEASCIIBYTErrsrrlengthrR ValueErrorwarningswarn)ryrrrZ basetypesris_ifddestr2rr6r s~       zImageFileDirectory_v2._setitemcCs.|j|d|j|d|j|ddSrl)rpoprrrr2r2r6 __delitem__sz!ImageFileDirectory_v2.__delitem__ Iterator[int]cCstt|jt|jBSrl)iterrrrrr2r2r6__iter__szImageFileDirectory_v2.__iter__r)rrrZcCst|j||Srl)runpackr)ryrrr2r2r6rszImageFileDirectory_v2._unpack)rrrZcGstj|j|g|RSrl)rpackr)ryrrr2r2r6rszImageFileDirectory_v2._packHshortr;longbz signed bytehz signed shortlz signed longrreddoublerZlong8rT)rrrZcCs|Srlr2rr2r2r6 load_byteszImageFileDirectory_v2.load_bytezbytes | int | IFDRationalrrZcCs*t|trt|}t|tr&t|f}|Srl)rrfr`rWryrr2r2r6 write_bytes    z ImageFileDirectory_v2.write_byter+cCs"|dr|dd}|ddS)Nrczlatin-1r)endswithdecoderr2r2r6 load_strings  z!ImageFileDirectory_v2.load_stringzstr | bytes | intcCs0t|trt|}t|ts(|dd}|dS)Nr rr5)rr`rwrWrryrr2r2r6 write_string%s    z"ImageFileDirectory_v2.write_stringr.r1z)tuple[tuple[int, int] | IFDRational, ...]cs`|t|dd|}ddddfdd tfdd t|ddd |d dd DS) Nr-r;r`tuple[int, int] | IFDRationalar,rZcsr ||fSt||Srlrfr=r,rr2r6combine4sz4ImageFileDirectory_v2.load_rational..combinec3s|]\}}||VqdSrlr2r3numdenomrAr2r6rS7r8z6ImageFileDirectory_v2.load_rational..r+rrrRrszipryrrvalsr2rArr6 load_rational.sz#ImageFileDirectory_v2.load_rationalrf)rrZcsdfdd|DS)Nr8c3s&|]}jdgt|dRVqdS)Z2LlN)rrjr3rurr2r6rS;sz7ImageFileDirectory_v2.write_rational..rrr2rr6write_rational9sz$ImageFileDirectory_v2.write_rationalr0cCs|Srlr2rr2r2r6load_undefined?sz$ImageFileDirectory_v2.load_undefinedcCs0t|trt|}t|tr,t|dd}|S)Nr r)rrfr`rwrr9r2r2r6write_undefinedCs   z%ImageFileDirectory_v2.write_undefined cs`|t|dd|}ddddfdd tfdd t|ddd |d dd DS) Nr-r.r`r;r<csr ||fSt||Srlr>r?r@r2r6rAQsz;ImageFileDirectory_v2.load_signed_rational..combinec3s|]\}}||VqdSrlr2rBrEr2r6rSTr8z=ImageFileDirectory_v2.load_signed_rational..r+rrFrHr2rJr6load_signed_rationalKsz*ImageFileDirectory_v2.load_signed_rationalcsdfdd|DS)Nr8c3s(|] }jdgt|ddRVqdS)Z2liiN)rrvrLrr2r6rSXsz>ImageFileDirectory_v2.write_signed_rational..rrr2rr6write_signed_rationalVsz+ImageFileDirectory_v2.write_signed_rational IO[bytes])fprrZcCs8||}t||kr4d|dt|d}t||S)Nz&Corrupt EXIF data. Expecting to read  bytes but only got z. )readrROSError)ryrTrretrr2r2r6 _ensure_read]s  z"ImageFileDirectory_v2._ensure_read)rTrZc Cs|||_z0|jr0|d||dn|d||dd}t|D]}|jrp|d||dn|d||d \}}}}t||j j }t |d } d |d |d | d |d } z|j |\} } Wn$tytd| |YqPYn0|| } | |jrdndkrt|}||jr4dnd|\}| d|d|7} ||t|| }||n |d| }t|| krtd| dt|d|t| qP|st| qP||j|<||j|<| d| dkrd| nt|7} t| qP|jr*|d||dn|d||d\|_Wn6tyz} ztt| WYd} ~ dSd} ~ 00dS)Nrr1r)r+rZHHQ8sHHL4sr<unknownztag:  ( ) - type: )z%s - unsupported type %sr-r;z Tag Location: z - Data Location: z/Possibly corrupt EXIF data. Expecting to read rUz. Skipping tag - value: rC)rtellrrrrYrangerrrrrgetrKeyErrorloggerdebugseekr _safe_readrRrrrrrrrWrw)ryrTZ tag_countrorrcountrtagnametypnamerZ unit_sizerrhereoffsetr2r2r6loadgst               zImageFileDirectory_v2.loadr)rnrZc s8|dt|j}g}t|t|jddd}t|jD]\}}|tkr`t|}|j|}td||t ||t j kot |t }|r|jdkrd} nd} t| |d} |j|} | D]\} } | | | <q| }n*t |tr|n|f} |j||g| R}t ||jj}|r*d n t|d }d |d |d |d |d }|dt|dkrrdt|nt| 7}t||rd}n(|t jt jt jfvrt|}nt| }t|dkr|||||dddfqF|||||d|ft|ddd7qF|dur||\}}}}}|r|j|\}}fdd||||jD} |j||g| R}n|d| d|d}|||||f||<|D]B\}}}}}td|||t |t |||d||||7}q|d7}|D].\}}}}}||7}t|d@r|d7}q|S)Nr)r<r-zTag %s, Type: %s, Value: %srsII*sMM*)rifdr\zsave: r]r^r_r`r>rarr5r8r;r+csg|] }|qSr2r2)r3rarnr2r6rr8z1ImageFileDirectory_v2.tobytes..rz%s %s %s %s %sr[s)!rrRrsortedr STRIPOFFSETSrrfrgrrrrrrrtobytesrsrrrrrrdrwrrrappendljustrrr)ryrnresultentriesZ stripoffsetsrrrr rrprZifd_tagZ ifd_valuerrkrlrrjrrr2rqr6rtsl           zImageFileDirectory_v2.tobytescCsN|dkr&||j|ddd|}||}|||t|S)NrZHL*r1)rbwriterrrtrR)ryrTrnrwr2r2r6saves    zImageFileDirectory_v2.save)rNN)T)T)T)T)T)r)6rrrrr__annotations__rrrrYrnrsetterrrrrrrr r r#r&rrlistmaprrrrZ SIGNED_BYTErrFLOATrZIFDZLONG8rr1rr4r8r:rKrMrNrOrQrRrYrortr{r2r2r2r6rs <  '    P            COrrrZwrite_cseZdZUdZddddfdd ZeddZed dZd ed <e d dd ddZ d dddZ dddddZ ddddZ ddddZdddddd Zdddd!d"ZZS)#ImageFileDirectory_v1aThis class represents the **legacy** interface to a TIFF tag directory. Exposes a dictionary interface of the tags in the directory:: ifd = ImageFileDirectory_v1() ifd[key] = 'Some Data' ifd.tagtype[key] = TiffTags.ASCII print(ifd[key]) ('Some Data',) Also contains a dictionary of tag types as read from the tiff image file, :attr:`~PIL.TiffImagePlugin.ImageFileDirectory_v1.tagtype`. Values are returned as a tuple. .. deprecated:: 3.0.0 r r)rzkwargsrZcstj|i|d|_dS)NT)superrr)ryrzr __class__r2r6r!szImageFileDirectory_v1.__init__cCs|jSrl)rrr2r2r6r%r8zImageFileDirectory_v1.cCs|jSrl)rrr2r2r6r&r8zdict[int, int]rr)originalrZcCs(||jd}|j|_|j|_|j|_|S)a2Returns an :py:class:`~PIL.TiffImagePlugin.ImageFileDirectory_v1` instance with the same data as is contained in the original :py:class:`~PIL.TiffImagePlugin.ImageFileDirectory_v2` instance. :returns: :py:class:`~PIL.TiffImagePlugin.ImageFileDirectory_v1` r])rYrrr)clsrrpr2r2r6from_v2,s zImageFileDirectory_v1.from_v2rcCs4t|jd}t|j|_t|j|_t|j|_|S)a2Returns an :py:class:`~PIL.TiffImagePlugin.ImageFileDirectory_v2` instance with the same data as is contained in the original :py:class:`~PIL.TiffImagePlugin.ImageFileDirectory_v1` instance. :returns: :py:class:`~PIL.TiffImagePlugin.ImageFileDirectory_v2` r])rrYrrrr)ryrpr2r2r6to_v2>s    zImageFileDirectory_v1.to_v2rrXrcCs||jvp||jvSrl)rrrr2r2r6rOsz"ImageFileDirectory_v1.__contains__r`cCstt|jt|jBSrl)rRrrrrr2r2r6rRszImageFileDirectory_v1.__len__r$cCstt|jt|jBSrl)r%rrrrr2r2r6r&UszImageFileDirectory_v1.__iter__rcCsdD]}||||qdSN)FT)r )ryrrrr2r2r6r Xsz!ImageFileDirectory_v1.__setitem__cCsn||jvrL|j|}|j|}|j|\}}dD]}|||||||q0|j|}t|ttfsj|f}|Sr)rrrrr rrsrW)ryrrrrrlegacyrar2r2r6r\s    z!ImageFileDirectory_v1.__getitem__)rrrrrrtagsZtagdatar| classmethodrrrrr&r r __classcell__r2r2rr6rs   rcseZdZdZdZdZd&ddddfd d Zdd d d Zedd ddZ dddddZ dddddZ dd ddZ dd ddZ dd fdd Zdd ddZdd d d!Zdd d"d#Zdd d$d%ZZS)' TiffImageFileZTIFFz Adobe TIFFFNStrOrBytesPath | IO[bytes]zstr | bytes | Noner)rTfilenamerZcs||t||dSrl)rr)ryrTrrr2r6rvszTiffImageFile.__init__rcCs|jd}|ddkr(||jd7}t||_|jj|_|_d|_|j|_g|_ d|_ t dt d|jt dt ||d dS) z#Open the first image in a TIFF filer1r+rrcNz*** TiffImageFile._open ***z - __first: %sz - ifh: %sr)rTrVrtag_v2rZ_TiffImageFile__first_TiffImageFile__next_TiffImageFile__frame_fp _frame_pos _n_framesrfrgr_seek)ryrr2r2r6_opens    zTiffImageFile._openr`cCsb|j}|durN|}|t|j|jdurD||dq&|||jdus\J|jS)Nr)rrbrrRrrh)ryZcurrent_n_framescurrentr2r2r6n_framess  zTiffImageFile.n_frames)framerZcCsH||sdS|||jdurD|jj|jks>|jj|jkrDd|_dS)z%Select a given frame as current imageN)Z _seek_checkr_imimr _tile_sizemode)ryrr2r2r6rhs     zTiffImageFile.seekcCs~|j|_|jt|j|kr|js2d}t|td||j |j|j|jdkrdd}t ||j |j|j |jtd|j|j |j|j j|jvrd|_n |j j|_|jdkr|d|_t|jdkr|jdk|_|j d7_ q|j |j||j |jt|j vr<|j t|jd<nd|jvrP|jd=|t|j |_|_||_ |dS) Nzno more images in TIFF filez9Seeking to frame %s, on frame %s, __next %s, location: %slzUnable to seek to framezLoading tags, location: %srrZxmp)rrTrbrRrrEOFErrorrfrgrrrhrurrorr is_animatedXMPrZ _reload_exifrrrrp_setup)ryrrr2r2r6rsL        zTiffImageFile._seekcCs|jS)zReturn the current frame number)rrr2r2r6rbszTiffImageFile.tellzdict[int, dict[str, bytes]]cCsi}|jtjj}|r|dddkrt|dd}t|dddd}t|d|d|}|d|d||}d|i||<|td||ddd}q|S) a5 Returns a dictionary of Photoshop "Image Resource Blocks". The keys are the image resource ID. For more information, see https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/#50577409_pgfId-1037727 :returns: Photoshop "Image Resource Blocks" in a dictionary. Nr-s8BIMr/rr+rPr) rrdrBaseZImageResourcesi16mathceili32)ryblocksraidnrrr2r2r6get_photoshop_blockss $z"TiffImageFile.get_photoshop_blockszImage.core.PixelAccess | Nonecs|jr|jr|StSrl)tileuse_load_libtiff _load_libtiffrrorrr2r6ros zTiffImageFile.loadcCs:|jdur*t|jtj|j|j|_tj |dSrl) rrZ_decompression_bomb_checkrcorenewrrr load_preparerr2r2r6rs  zTiffImageFile.load_preparecCsj|js>d|_|j|}tjD]}||vr2q$||q$tj |ddt j j |j vrf|j t j j =dS)NT)Zin_place)r!_close_exclusive_fp_after_loadingrTrbZgetexifrTAGS_V2_GROUPSget_ifdrZexif_transposerr Orientationr)ryexifkeyr2r2r6load_ends   zTiffImageFile.load_endc Cstj||t|jdks.d}t||jdd}|jdd}z0t|jdo`|j}t|jdrx|j Wntyd}Yn0|rt |t sJt |}||d<t |}t |jd ||j}z||j|Wn4ty}zd }t||WYd }~n d }~00|jo&|j }t|jd rVtd ||j\} } n\|rtd|sx|jd|d\} } n*td|jd||j\} } g|_d|_||r|jd |_| dkrt| tj|S)zWOverload method triggered when we detect a compressed tiff Calls out to libtiffrzNot exactly one tilerr,filenoflushFr+libtiffzCouldn't set the imageNgetvaluez5have getvalue. just sending in a string from getvaluez3have fileno, calling fileno version of the decoder.sfpfpz+don't have fileno or getvalue. just reading)rrorrRrrWrrTrrrrsr~Z _getdecoderrZ decoderconfigsetimagerrZ _exclusive_fprrfrgr7rrhrVreadonlyrclose) ryrZextentsrzrTZ args_listdecodereZ close_self_fprerrr2r2r6rsZ            zTiffImageFile._load_libtiffc Csld|jvrd}t|t|jtd|_|jtd|_|jtd}|jdkrVd}|jt d}t dt d|jt d |t d |jt d |t d |jt |jt }|jt}t|trt|tsd }t|||f|_|jtjj}|dvr||f|_n ||f|_t d|j|jtd}t|dkrzt|t|krrdkrznnd}|jtd}|jtd} |dvrd} n|dkrd} nd} | t| 7} t|} |jt|jdkr|dvrdnd} | tkrt d| d}t!|| | kr0|d| }n| | krL| dkrL|| }t|| krfd}t!||jj"||||| f} t d| zt#| \|_$}Wn>t%y}z$t dd}t!||WYd}~n d}~00t d|t d|j&|j|j'd <|jt(d}|jt)d}|r|r|jt*}|d!krL||f|j'd"<nX|dkrn|d#|d#f|j'd"<n6|dur||f|j'd"<||f|j'd$<n||f|j'd$<d}}}g|_+t,p|jd%k|_-|j-r|d!kr| ddd| dd} t d| t#| \|_$}|d&krd'}d(|vr4|.d(d)}d*|vrJ|.d*d)}|dkrp|jd+krp|jdkrpd,}||jd-|jj/f}|j+0t12d.dd||fd|nrt3|jvst4|jvrt3|jvr|jt3}|jt5|}|}nJ|jt4}|jt6}|jt7}t|tr"t|ts.d/}t||}|D]}|||krZ|t8|d0}nd}|}|jd!kr~||}|| }|t|df}|j+0t12|j||t|||t|||f||||}||kr6d||}}||kr6d}}|d7}q6nt d1d}t!|t9|jvr4|jt9|j'd2<|j&d3vrhd4d5|jt:D}t;dS)8z-Setup this image object based on current tagsiz+Windows Media Photo files not yet supportedrrr&r/z*** Summary ***z- compression: %sz - photometric_interpretation: %sz- planar_configuration: %sz- fill_order: %sz- YCbCr subsampling: %szInvalid dimensions)r.r/r0r1z - size: %sr9r2)r+r/r1r,r.r-)r+r/z.More samples per pixel than can be decoded: %sz#Invalid value for samples per pixelNzunknown data organizationzformat key: %sz- unsupported formatzunknown pixel modez- raw mode: %sz- pil mode: %s compressionr+dpigRQ@ resolutionr%r=I;16Nz;16Bz;16Nz;16Lr'rJFrzInvalid tile dimensionsr1z- unsupported data organization icc_profilerNrOcSsg|]}t|dqSr"r)r3r,r2r2r6rZr8z(TiffImageFile._setup..RGB;Lr8)?rrWCOMPRESSION_INFOrd COMPRESSION _compressionPLANAR_CONFIGURATIONZ_planar_configurationPHOTOMETRIC_INTERPRETATION FILLORDERrfrgYCBCRSUBSAMPLING IMAGEWIDTH IMAGELENGTHrr`rrrrr_sizer SAMPLEFORMATrRrtrr BITSPERSAMPLE EXTRASAMPLESSAMPLESPERPIXELMAX_SAMPLESPERPIXELerrorrrY OPEN_INFO_modererr X_RESOLUTION Y_RESOLUTIONRESOLUTION_UNITr READ_LIBTIFFrrrnrur_Tilers TILEOFFSETS ROWSPERSTRIP TILEWIDTH TILELENGTHsum ICCPROFILECOLORMAPrr%rpalette) ryrphotoZ fillorderZxsizeZysizeZ orientationZ sample_formatZ bps_tupleZ extra_tupleZ bps_countZbps_actual_countZsamples_per_pixelrrawmoderZxresZyresZresunitxylayerr=offsetsr-wZ tilewidthrnstrideZ tile_rawmoderzrr2r2r6rqs,           2                       $           zTiffImageFile._setup)N)rrrformatformat_descriptionrrrrrrhrrbrrorrrrrr2r2rr6rqs"   0Vrr:r;rIrNrOrGr=rArErJrLrKrPYCbCrrQrHr?rBrF)r:r;rIrNrOr@r=rArDrJrLrKrPrrQrHr?rBrFz Image.ImagerSz str | bytes)rrTrrZc6 Csd zt|j\}}}}}}Wn<tyV} z$d|jd} t| | WYd} ~ n d} ~ 00t|d} |j} |j} z | d}Wn,ty|jd}t |t rd}Yn0|durd}n|dkrd}n |dkrd }t p|dk}d | t <|j d | t<|j d | t<d | vr| d }n:d | vrJ| d }t |trNt}|||}ni}tdt|t |trr|}|D]h}t |tjr|tjvr||| |<n||| |<z|j|| j|<WntyYn0qvi}t|dr|j}i|t |di}t!t"fD]}||vr||=qt|drt#t$t%t&t't(fD]^}||j)vrJ|t&kr|j)j|tj*tj+fvr||=n |j)|| |<|j)j|| j|<qJ| d|jd}|r|| t,<t-dft$dft%dft$dft%dft#dft.dft/dft0dft1dff D] \}}|| vr | || |<q | d}|r^d| t#<|d | t$<|d | t%<|dkr|| t2<t3|d krt3|| t4<|dur|| t5<|d kr|| t"<t6| vr|| t6<n|jdvrX| t6d krX|jdkrN|7}|}|durXt8|j9D]:}t8|j:D](}|||fd kr4d nd |||f<qq |}n t;<|}|jd!vr|j=>d"d#}g}t3|d$}t8d$D]>} |d%d&||| || d D7}|d gd'|7}q|| t?<| t| t}!}"t3||!|d d(d)}#t@| vrt|rZ| d*tA}$|#d kr*d n tB|$|#|"}%|dkr^tB|%d(d)d)|"}%n|"}%|%d krld }%|%| t@<|#d krd n |#| t@}&|"| t@d | t@}'|&d+krtjC| jtD<|&f|'d |#|"|&|'d f| tD<tEt8d |&|'|&| tF<tG|d | tH<|jd,kr@tId-tJd.iKD]\}}(| L||(q(tMtNtOtPg})| rd/| vr| d/}*t |*t r|*d ks|*d0krd1} tQ| |dkrd2} tQ| |*| tR<td3td4tS| Kd }+t|d5r z|Td |U}+WntVjWyYn0i},|)tXtJtDtFtYtZg7})t2|d i}-t[\| K|KD]\}}.|tj]vrt tj^d6d7sjqB|| jvr| j||,|<n4t |.t t_t`tfsqBnta|jb}/|/r|/|,|<||-vrB||)vrBt |.t`r|.cd8d9d:|-|<n"t |.tdr t_|.|-|<n|.|-|<qBt"|-vrBt3|-t"d krB|-t"d |-t"<td;tS|-K|jd|1| }2|2g|j=d?|j |2cthjid d\}3}4|+s|j|4|3rqq|3d k rJd@|3dA} t| nD|)D] }| |= q | k|}5thl||thmdd?|j |5||#d fgdB| v r`tn|dB| dS)CNzcannot write mode z as TIFFr]rr%r&r'r)r(rrZtiffinforzTiffinfo Keys: %srrr descriptionrZ x_resolutionZ y_resolutionZresolution_unitZsoftware date_timeZartist copyrightrr+r9)r:r;r:r!rrJrr,cSsg|] }|dqSrr2r r2r2r6rr8z_save..r"r0r1Z strip_sizer r)rr)rr!r!rr!qualitydzInvalid quality settingz5quality setting only supported for 'jpeg' compressionzSaving using libtiff encoderz Items: %srrVFr rr5zConverted items: %s)r?r=rrrMzencoder error z when writing image fileZ_debug_multipage)o SAVE_INFOrrerWr encoderinfo encoderconfigrrdrr` WRITE_LIBTIFFrrrrrWrZExifrorfrgr~rrrrrrrrrr{EXIFIFDrrrrIPTC_NAA_CHUNKPHOTOSHOP_CHUNKrrrrrIMAGEDESCRIPTIONSOFTWARE DATE_TIMEARTIST COPYRIGHTrrRrrrcopyrcheightwidthrinvertrZ getpaletterr STRIP_SIZErrrSTRIPBYTECOUNTSrsrsCOMPRESSION_INFO_REVrrREFERENCEBLACKWHITEr setdefaultrrrTILEBYTECOUNTSr JPEGQUALITYrrrhrioUnsupportedOperation OSUBFILETYPETRANSFERFUNCTIONSUBIFD itertoolschainZ LIBTIFF_CORErrerwrrrrfsortZ _getencoderrrZMAXBLOCKrzr{_saversetattr)6rrTrrrYrrbitsextrarrrprrrrrrrZ legacy_ifdZ supplied_tagsrZiccrrZ inverted_imZpxrrZlutZcolormapcolorsrorr-rZ im_strip_sizeZrows_per_stripZstrip_byte_countsZstrips_per_image default_valueZ blocklistrrtypesZattsrrrr=encodererrcoderrnr2r2r6r~s                                 *    &                                 rc@seZdZgdZhdZdOdddddd Zdd d d Zdd d dZdd ddZdd ddZ dddddZ dd ddZ e j fddddddZdd ddZddd d!d"Zdd d#d$Zd%dd&d'd(Zddd)d*d+Zddd)d,d-Zdd d.d/Zdd d0d1Zed2ddd3d4d5Zddd6d7d8Zdddd9d:d;Zddd6dd?Zddd6d@dAZddd6dBdCZdd dDdEZdd dFdGZ ddddHdIdJZ!dPdddddKdLdMZ"dNS)QAppendingTiffWriter)rrrr+r-r1rrr+r-r1r-r1r-r+r-r1>i r$iii r#FrrXr)fnrrZcCs|t|rR||_d|_zt||r&dnd|_WqhtyNt|d|_Yqh0nttt||_d|_|j |_ | dS)NTzw+bzr+bF) rrclose_fpopenrrWr rrWrb beginningsetup)ryr&rr2r2r6rs  zAppendingTiffWriter.__init__rcCs|j|jtjd|_d|_|jd|_}|s>d|_ dSd|_ |dkrX| dn |dkrl| dn d }t || | dS) Nrr-TFrUrrTrzInvalid TIFF file header)rrhr)osSEEK_SETwhereToWriteNewIFDOffsetoffsetOfNewPagerVIIMMisFirst setEndian RuntimeErrorskipIFDsgoToEnd)ryiimmrr2r2r6r*s   zAppendingTiffWriter.setupcCs|jr dS|j|j|jd}|s,dS||jkrBd}t||}||j7}|jdusbJ|j|j| ||j|| dS)Nr-z1IIMM of new page doesn't match IIMM of first page) r0rrhr.rVr/r2readLongr- writeLongfixIFD)ryr5r ifd_offsetr2r2r6finalizes      zAppendingTiffWriter.finalizecCs||dSrl)r:r*rr2r2r6newFrame szAppendingTiffWriter.newFramecCs|Srlr2rr2r2r6 __enter__szAppendingTiffWriter.__enter__r)rzrZcGs|jr|dSrl)r'rr}r2r2r6__exit__szAppendingTiffWriter.__exit__r`cCs|j|jSrl)rrbr.rr2r2r6rbszAppendingTiffWriter.tell)rnwhencerZcCs*|tjkr||j7}|j|||S)z :param offset: Distance to seek. :param whence: Whether the distance is relative to the start, end or current position. :returns: The resulting position, relative to the start. )r+r,r.rrhrb)ryrnr>r2r2r6rhs  zAppendingTiffWriter.seekcCs^|jdtj|j}d|d}d|kr:dkrNnn|jt||j|_dS)Nrr>)rrhr+SEEK_ENDrbrzrWr.)ryposZ pad_bytesr2r2r6r4)s   zAppendingTiffWriter.goToEndrw)endianrZcCs4||_|jd|_|jd|_|jd|_dS)Nr;r)ZHHL)rAlongFmtshortFmt tagFormat)ryrAr2r2r6r13szAppendingTiffWriter.setEndiancCsP|}|dkr"|jd|_qL|j||}|j|dtjqdS)Nrr-r<)r6rrbr-rh readShortr+SEEK_CUR)ryr9num_tagsr2r2r6r39s zAppendingTiffWriter.skipIFDsrr2cCs |j|Srl)rrzr3r2r2r6rzDszAppendingTiffWriter.write) field_sizerZcCs6zdddd|WSty0d}t|Yn0dS)Nr)r;r)r+r-r1zoffset is not supported)rer2)ryrHrr2r2r6_fmtGs  zAppendingTiffWriter._fmtcCs&t|j|||j|\}|Srl)rr'rArIrrV)ryrHrr2r2r6_readNszAppendingTiffWriter._readcCs |dSNr+rJrr2r2r6rETszAppendingTiffWriter.readShortcCs |dSr[rLrr2r2r6r6WszAppendingTiffWriter.readLongr) bytes_writtenexpectedrZcCs,|dur(||kr(d|d|}t|dS)Nz wrote only z bytes but wanted )r2)rMrNrr2r2r6_verify_bytes_writtenZsz)AppendingTiffWriter._verify_bytes_writtenrcCs6|jdtj|jt|j|}||ddS)Nr-) rrhr+rFrzrr(rBrOryrrMr2r2r6rewriteLastShortToLong`sz*AppendingTiffWriter.rewriteLastShortToLong)rrHrZcCsB|j| tj|jt|j|||}| ||dSrl) rrhr+rFrzrr(rArIrO)ryrrHrMr2r2r6 _rewriteLastes z AppendingTiffWriter._rewriteLastcCs ||dSrKrSr9r2r2r6rewriteLastShortlsz$AppendingTiffWriter.rewriteLastShortcCs ||dSr[rTr9r2r2r6rewriteLastLongosz#AppendingTiffWriter.rewriteLastLongcCs&|jt|j|}||ddSrK)rrzrr(rCrOrQr2r2r6 writeShortrszAppendingTiffWriter.writeShortcCs&|jt|j|}||ddSr[)rrzrr(rBrOrQr2r2r6r7vszAppendingTiffWriter.writeLongcCs||jr|jdSrl)r:r'rrrr2r2r6rzszAppendingTiffWriter.closec Cs|}t|D]}t|j|jd\}}}|j|}||}|dk}|sf||j } | | ||j vr|j } |r| |||j| dq|j| | |||j| q|r|jdtjqdS)Nr1r-)rErcrr'rDrrV fieldSizesr6r.rVTagsrb _fixOffsetsrhr+rF) ryrGrorZ field_typerjrH total_sizeis_localrnZcur_posr2r2r6r8s&        zAppendingTiffWriter.fixIFD)rjrHrZcCst|D]}||}||j7}|dkr||dkr||dkrDd}t||||jdtj| t j |jdtjq| ||qdS)Nr+r rznot implementedir1) rcrJr.r2rRrrhr+rFrWrrrS)ryrjrHrornrr2r2r6rZs     zAppendingTiffWriter._fixOffsets)rjisShortisLongrZcCs$|r d}n|rd}nd}|||S)Nr+r-r)rZ)ryrjr]r^rHr2r2r6 fixOffsetss zAppendingTiffWriter.fixOffsetsN)F)FF)#rrrrXrYrr*r:r;r<r=rbrr,rhr4r1r3rzrIrJrEr6 staticmethodrOrRrSrUrVrWr7rr8rZr_r2r2r2r6r%s>    r%c Cs|j}|j}t|dg}t|ds:|s:t|||S|}zt|v}|g|D]Z}||_||_t|dsxd} n|j } t | D]*} | | | t|||| qqXWdn1s0YW| |n | |0dS)N append_imagesrr)rr rr~rdrrrbr%rrcrhror;) rrTrrrraZcur_idxtfZimsZnfrrr2r2r6 _save_alls(       ,rcz.tifz.tiffz image/tiff) __future__rrrloggingrr+rrcollections.abcrr fractionsrnumbersrrtypingrr r r r r rrrrrr_binaryrrrrrZ _deprecaterZ_typingrZ_utilrrrr getLoggerrrfrrr rrrrrrrrrrrsrrrrrrrrrrrZ PREDICTORrrrrrrrrZ JPEGTABLESrrrrrrrrrZIMAGEJ_META_DATA_BYTE_COUNTSZIMAGEJ_META_DATArrrrrtrr\r{rr^rjrvrrrrfrWrXrrrrr`Z _IFDv2BaserrrrrrZImageFileDirectoryrrrBytesIOr%rcZ register_openrZ register_saveZregister_save_allZregister_extensionsZ register_mimer2r2r2r6)s(            ~      \z3