a
    
d                     @   s  d Z ddlmZmZmZ ddlZddlZddlZddlZddl	Z	ddl
Z
ddlZddlZddlZddlmZ eeZdZddd eD Zejd d	kZereZeZeZeZeZn&e   e!Ze"Ze!Zee#fZeej$fZe
j%Z&e
j'Z(d
d Z)dd Z*dd Z+dd Z,G dd de-Z.G dd de-Z/G dd de/Z0G dd de-Z1d)ddZ2d*ddZ3d+ddZ4d,d d!Z5e4Z6e2Z7G d"d# d#e-Z8G d$d% d%e8Z9G d&d' d'e8Z:e9e:gZ;ed(krddl<Z<e<=  dS )-a!  
Python implementation of the Binary Structured Data Format (BSDF).

BSDF is a binary format for serializing structured (scientific) data.
See http://bsdf.io for more information.

This is the reference implementation, which is relatively relatively
sophisticated, providing e.g. lazy loading of blobs and streamed
reading/writing. A simpler Python implementation is available as
``bsdf_lite.py``.

This module has no dependencies and works on Python 2.7 and 3.4+.

Note: on Legacy Python (Python 2.7), non-Unicode strings are encoded as bytes.
    )absolute_importdivisionprint_functionN)BytesIO)      r   .c                 c   s   | ]}t |V  qd S N)str.0i r   ^/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/imageio/plugins/_bsdf.py	<genexpr>0       r      c                 C   s"   | dkrt d| S t dd| S dS )z?Encode an unsigned integer into a variable sized blob of bytes.   <B<BQ   N)spack)xr   r   r   lencodeJ   s    
r   c                 C   s4   t d| dd }|dkr0t d| dd }|S )z'Decode an unsigned integer from a file.r   r   r   r   <Q   )	strunpackread)fnr   r   r   	lendecodeY   s    r    c                 C   s2   |dur*| d}|  tt| | S | S dS )z9Encode the type identifier, with or without extension id.NUTF-8)encodeupperr   len)bext_idbbr   r   r   encode_type_ida   s    
r(   c                 C   s*   t | to(td| tjo(td| du S )z8Use of str.isidentifier() for Legacy Python, but slower.z^\w+$z^[0-9]N)
isinstancestring_typesrematchUNICODE)sr   r   r   _isidentifierj   s
    
r/   c                   @   sd   e Zd ZdZdddZddd	Zd
d Zdd Zdd Zdd Z	dd Z
dd Zdd Zdd ZdS )BsdfSerializeraz  Instances of this class represent a BSDF encoder/decoder.

    It acts as a placeholder for a set of extensions and encoding/decoding
    options. Use this to predefine extensions and options for high
    performance encoding/decoding. For general use, see the functions
    `save()`, `encode()`, `load()`, and `decode()`.

    This implementation of BSDF supports streaming lists (keep adding
    to a list after writing the main file), lazy loading of blobs, and
    in-place editing of blobs (for streams opened with a+).

    Options for encoding:

    * compression (int or str): ``0`` or "no" for no compression (default),
      ``1`` or "zlib" for Zlib compression (same as zip files and PNG), and
      ``2`` or "bz2" for Bz2 compression (more compact but slower writing).
      Note that some BSDF implementations (e.g. JavaScript) may not support
      compression.
    * use_checksum (bool): whether to include a checksum with binary blobs.
    * float64 (bool): Whether to write floats as 64 bit (default) or 32 bit.

    Options for decoding:

    * load_streaming (bool): if True, and the final object in the structure was
      a stream, will make it available as a stream in the decoded object.
    * lazy_blob (bool): if True, bytes are represented as Blob objects that can
      be used to lazily access the data, and also overwrite the data if the
      file is open in a+ mode.
    Nc                 K   s@   i | _ i | _|d u rt}|D ]}| | q| jf i | d S r	   )_extensions_extensions_by_clsstandard_extensionsadd_extension_parse_options)self
extensionsoptions	extensionr   r   r   __init__   s    zBsdfSerializer.__init__r   FTc                 C   sh   t |tr&dddd}|| |}|dvr6td|| _t|| _t|| _t|| _	t|| _
d S )Nr   r   r   )nozlibbz2)r   r   r   z3Compression must be 0, 1, 2, "no", "zlib", or "bz2")r)   r*   getlower	TypeError_compressionbool_use_checksum_float64_load_streaming
_lazy_blob)r6   compressionuse_checksumfloat64Zload_streamingZ	lazy_blobmr   r   r   r5      s    	



zBsdfSerializer._parse_optionsc                 C   s   t |trt|tstd| }|j}t |ts:tdt|dksRt|dkrZtd|| j	v rrt
d|  |j}|sg }nt |ttfr|}n|g}|D ]}t |tstdq|D ]}||jf| j|< q|| j	|< |S )zAdd an extension to this serializer instance, which must be
        a subclass of Extension. Can be used as a decorator.
        z*add_extension() expects a Extension class.Extension name must be str.r   r   z<Extension names must be nonempty and shorter than 251 chars.zABSDF warning: overwriting extension "%s", consider removing firstz Extension classes must be types.)r)   type
issubclass	Extensionr@   namer
   r$   	NameErrorr1   loggerwarningclstuplelist
classtypesr"   r2   )r6   Zextension_classr9   rO   rS   Zclssr   r   r   r4      s@    




zBsdfSerializer.add_extensionc                 C   s^   t |tstd|| jv r(| j| t| j D ]"}| j| d |kr6| j| q6dS )z&Remove a converted by its unique name.rK   r   N)r)   r
   r@   r1   poprU   r2   keys)r6   rO   rS   r   r   r   remove_extension   s    

zBsdfSerializer.remove_extensionc                 C   s  t }|du r ||d| n|du r<||d| n||du rX||d| n`t|trd|  krvdkrn n||d	|td
|  n||d|td|  nt|tr| jr||d|td|  n||d|td|  nt|tr>|d}||d|t	t
|  || nzt|ttfr||d|t	t
|  |D ]}| |||d qnn.t|tr$||d|t	t
|  | D ]d\}}tr| sJ nt|sJ |d}	|t	t
|	 ||	 | |||d qnt|tr`||d| t|| j| jd}
|
| nXt|tr||d| || n.t|tr|jdkrtdn2t|tr||d|tddd  ntdt
|dkrtd|| ||| j| j n|dur(td| | j !|j"d}|du rz| j# D ](\}}|$| |rL||jf} qzqLd}|dur|\}}| ||| ||| nd}t||j"j% dS ) zMain encoder function.N   vT   yF   ni i     hh   i<q   d<d   f<fr!      s   l   m   b)rG   rH   wz$Cannot serialize a read-mode stream.r      r   zOnly ListStream is supportedz"Can only have one stream per file.zExtension %s wronfully encodes object to another extension object (though it may encode to a list/dict that contains other extension objects).zJClass %r is not a valid base BSDF type, nor is it handled by an extension.)&r(   writer)   integer_typesr   floatrD   unicode_typesr"   r   r$   rU   rT   _encodedictitemsPY3isidentifierr/   bytesBlobrA   rC   _to_file
BaseStreammode
ValueError
ListStreamr@   append	_activate_decoder2   r>   	__class__r1   r,   __name__)r6   r   valuestreamsr&   r   r'   vkeyZname_bblobexrO   cZext_id2Zextension_encodetr   r   r   ro      s    












zBsdfSerializer._encodec                    s    d}| }|st n2||krLtd  dd }  |d}nd}|dkr`d}n|dkrpd}n|d	krd
}n|dkrtd  dd }n|dkrtd  dd }n|dkrtd  dd }nd|dkrtd  dd }nB|dkrRtd  dd }|dkr>td  dd }  |d}n|dkrPtd  dd }|dkr|dk}td  dd }jrt|r|nd}| jj	 nR|r fddt
|D }n2g }z|	  qW n ty   Y n0 n6|dkr6td  dd } fddt
|D }n|dkrt }td  dd }|dkrtd  dd }t
|D ]d}	td  dd }
|
dkrtd  dd }
|
dksJ   |
d}	 ||< qnB|d kr8jr"t df}nt d
f}| }ntd!| |durj|d}|durt||}ntd"|  |S )#zMain decoder function.r   r   r   r!   NrZ   r[   Tr\   Fr]   z<hr   r_   r`   r   rc   rd      ra   rb   re   r   r   rf      rc                    s   g | ]}  qS r   r}   r   r   r6   r   r   
<listcomp>r  r   z*BsdfSerializer._decode.<locals>.<listcomp>c                    s   g | ]}  qS r   r   r   r   r   r   r   ~  r   rg   rh   zParse error %rz'BSDF warning: no extension found for %r)r   r?   EOFErrorr   decoderE   rz   r|   ro   r}   ranger{   rp   rF   ru   	get_bytesRuntimeErrorr1   r>   rQ   rR   )r6   r   charr   r   r&   r   Zn_sclosedr   Zn_namerO   r   r9   r   r   r   r}   D  s    













zBsdfSerializer._decodec                 C   s   t  }| || | S )zSave the given object to bytes.)r   savegetvalue)r6   obr   r   r   r   r"     s    zBsdfSerializer.encodec                 C   sx   | d | tdtd  | tdtd  g }| |||d t|dkrt|d }|j| krttddS )z0Write the given object to the given file object.   BSDFr   r   r   Nz8The stream object must be the last object to be encoded.)	rk   structpackVERSIONro   r$   
_start_postellry   )r6   r   r   r   streamr   r   r   r     s    
zBsdfSerializer.savec                 C   s   t |}| |S )z@Load the data structure that is BSDF-encoded in the given bytes.)r   load)r6   r'   r   r   r   r   r     s    zBsdfSerializer.decodec                 C   s   | d}|dkrtd| td| dd }td| dd }d||f }|td krrd}t|t|f |td krd	}t|t|f  | |S )
z6Load a BSDF-encoded object from the given file object.r   r   z'This does not look like a BSDF file: %rr   r   r   z%i.%izLReading file with different major version (%s) from the implementation (%s).zWBSDF warning: reading file with higher minor version (%s) than the implementation (%s).)r   r   r   r   __version__rQ   rR   r}   )r6   r   Zf4major_versionminor_versionZfile_versionr   r   r   r   r     s    
zBsdfSerializer.load)N)r   FTFF)r   
__module____qualname____doc__r:   r5   r4   rY   ro   r}   r"   r   r   r   r   r   r   r   r0   t   s    
     
+
[Zr0   c                   @   s.   e Zd ZdZd
ddZdd Zedd Zd	S )rw   zBase class for streams.ri   c                 C   sR   d| _ d| _t|tr"|| _d}n|dkr0d| _|dv s<J || _d | _d| _d S )Nr   r   ri   )r   ri   )_i_countr)   int_mode_fr   )r6   rx   r   r   r   r:     s    
zBaseStream.__init__c                 C   s4   | j d urtd|| _ | j  | _|| _|| _d S )Nz(Stream object cannot be activated twice?)r   IOErrorr   r   ro   r}   )r6   fileZencode_funcZdecode_funcr   r   r   r|     s    
zBaseStream._activatec                 C   s   | j S )z$The mode of this stream: 'r' or 'w'.)r   r6   r   r   r   rx     s    zBaseStream.modeN)ri   )r   r   r   r   r:   r|   propertyrx   r   r   r   r   rw     s
   
rw   c                   @   sR   e Zd ZdZedd Zedd Zdd Zdd	d
Zdd Z	dd Z
dd ZdS )rz   zjA streamable list object used for writing or reading.
    In read mode, it can also be iterated over.
    c                 C   s   | j S )zdThe number of elements in the stream (can be -1 for unclosed
        streams in read-mode).
        )r   r   r   r   r   count  s    zListStream.countc                 C   s   | j S )z/The current index of the element to read/write.)r   r   r   r   r   index  s    zListStream.indexc                 C   sj   | j | jkrtd| jdu r&td| jjr6td| | j|| gd |  jd7  _|  j d7  _ dS )zAppend an item to the streaming list. The object is immediately
        serialized and written to the underlying file.
        z/Can only append items to the end of the stream.Nz.List stream is not associated with a file yet.zCannot stream to a close file.r   )r   r   r   r   r   ro   )r6   itemr   r   r   r{     s    
zListStream.appendFc                 C   s   | j | jkrtd| jdu r&td| jjr6td| j }| j| jd d  | jt	d|rhdnd	 | jt	d
| j  | j| dS )zClose the stream, marking the number of written elements. New
        elements may still be appended, but they won't be read during decoding.
        If ``unstream`` is False, the stream is turned into a regular list
        (not streaming).
        z-Can only close when at the end of the stream.N-ListStream is not associated with a file yet.z&Cannot close a stream on a close file.r   r   r   r   r   r   )
r   r   r   r   r   r   seekr   rk   r   )r6   Zunstreamr   r   r   r   close  s    

zListStream.closec                 C   s   | j dkrtd| jdu r$tdt| jddr:td| jdkrp| j| jkrVt |  jd7  _| | jS z | | j}|  jd7  _|W S  ty   | j| _t Y n0 dS )	zyRead and return the next element in the streaming list.
        Raises StopIteration if the stream is exhausted.
        r   z$This ListStream in not in read mode.Nr   r   z'Cannot read a stream from a close file.r   r   )	r   r   r   getattrr   r   StopIterationr}   r   )r6   resr   r   r   next,  s$    


zListStream.nextc                 C   s   | j dkrtd| S )Nr   z/Cannot iterate: ListStream in not in read mode.)r   r   r   r   r   r   __iter__E  s    
zListStream.__iter__c                 C   s   |   S r	   )r   r   r   r   r   __next__J  s    zListStream.__next__N)F)r   r   r   r   r   r   r   r{   r   r   r   r   r   r   r   r   rz     s   


rz   c                   @   sb   e Zd ZdZdddZdd Zdd	 Zd
d Zdd Zdd Z	dd Z
dd Zdd Zdd ZdS )ru   a8  Object to represent a blob of bytes. When used to write a BSDF file,
    it's a wrapper for bytes plus properties such as what compression to apply.
    When used to read a BSDF file, it can be used to read the data lazily, and
    also modify the data if reading in 'r+' mode and the blob isn't compressed.
    r   Fc                 C   s   t |tr8d | _| ||| _|| _| j| | _|| _nRt |t	rt
|dkrt|d dr|\| _}d | _| | j| d| _ntdd S )Nr   r   r   FzWrong argument to create Blob.)r)   rt   r   _from_bytes
compressedrG   	used_sizeallocated_sizerH   rT   r$   hasattr
_from_file	_modifiedr@   )r6   r'   rG   
extra_sizerH   
allow_seekr   r   r   r:   X  s    
$
zBlob.__init__c                 C   s^   |dkr|}n8|dkr$t |d}n"|dkr:t|d}ndsFJ dt|| _t|| _|S )z"When used to wrap bytes in a blob.r   r   	   r   FzUnknown compression identifier)r<   compressr=   r$   	data_sizer   )r6   r   rG   r   r   r   r   r   g  s    

zBlob._from_bytesc                 C   s:  | j dkrJ| jdkrJ|td| j  |td| j |t| j n<|tdd| j  |tdd| j |tdd| j |td| j | jr|dt	| j
   n
|d | jdkrd	| d
 d	  }|td| |d|  n|tdd || j
 |d| j | j   dS )zBPrivate friend method called by encoder to write a blob to a file.r   r   r   r   r   B       r   r   N)r   rG   rk   r   r   r   r   rH   hashlibmd5r   digestr   )r6   r   	alignmentr   r   r   rv   v  s$    
zBlob._to_filec           
      C   sj  t d|dd }|dkr0t d|dd }t d|dd }|dkr`t d|dd }t d|dd }|dkrt d|dd }t d|dd }t d|dd }|r|d}t d|dd }	||	 |r| | _| j| | _|| j|  n&d| _d| _||| _|||  |	| _|| _|rN|nd| _	|| _
|| _|| _dS )	z(Used when a blob is read by the decoder.r   r   r   r   r   r      N)r   r   r   	start_posend_posr   r   r   rG   rH   r   r   r   )
r6   r   r   r   r   r   rG   Zhas_checksumZchecksumr   r   r   r   r     s:    


zBlob._from_filec                 C   sT   | j du rtd|dk r$| j| }|dk s6|| jkr>td| j | j|  dS )z8Seek to the given position (relative to the blob start).Nz>Cannot seek in a blob that is not created by the BSDF decoder.r   zSeek beyond blob boundaries.)r   r   r   r   r   r   )r6   pr   r   r   r     s    

z	Blob.seekc                 C   s"   | j du rtd| j  | j S )zCGet the current file pointer position (relative to the blob start).Nz>Cannot tell in a blob that is not created by the BSDF decoder.)r   r   r   r   r   r   r   r   r     s
    
z	Blob.tellc                 C   sR   | j du rtd| jr td| j  t| | jkr@tdd| _| j |S )zWrite bytes to the blob.Nz?Cannot write in a blob that is not created by the BSDF decoder.z,Cannot arbitrarily write in compressed blob.zWrite beyond blob boundaries.T)	r   r   rG   r   r   r$   r   r   rk   )r6   r'   r   r   r   rk     s    
z
Blob.writec                 C   sH   | j du rtd| jr td| j  | | jkr<td| j |S )zRead n bytes from the blob.Nz>Cannot read in a blob that is not created by the BSDF decoder.z+Cannot arbitrarily read in compressed blob.zRead beyond blob boundaries.)r   r   rG   r   r   r   r   )r6   r   r   r   r   r     s    
z	Blob.readc                 C   s   | j dur| j }n.| j }| d | j| j}| j| | jdkrP|}n:| jdkrft|}n$| jdkr|t	|}nt
d| j |S )z&Get the contents of the blob as bytes.Nr   r   r   zInvalid compression %i)r   r   r   r   r   r   rG   r<   
decompressr=   r   )r6   r   r   r   r   r   r   r     s    





zBlob.get_bytesc                 C   sZ   | j rV| jrV| d | j| j}| j| j| j d d  | jt	
|  dS )zZReset the blob's checksum if present. Call this after modifying
        the data.
        r   r   r   N)rH   r   r   r   r   r   r   r   rk   r   r   r   )r6   r   r   r   r   update_checksum  s
    
zBlob.update_checksumN)r   r   F)r   r   r   r   r:   r   rv   r   r   r   rk   r   r   r   r   r   r   r   ru   N  s   	
'ru   c                 K   s   t |fi |}|| S )zrSave (BSDF-encode) the given object to bytes.
    See `BSDFSerializer` for details on extensions and options.
    )r0   r"   )r   r7   r8   r.   r   r   r   r"     s    r"   c                 K   sb   t |fi |}t| trRt| d}|||W  d   S 1 sF0    Y  n|| |S dS )zSave (BSDF-encode) the given object to the given filename or
    file object. See` BSDFSerializer` for details on extensions and options.
    wbN)r0   r)   r*   openr   )r   r   r7   r8   r.   fpr   r   r   r     s
    
,r   c                 K   s   t |fi |}|| S )zpLoad a (BSDF-encoded) structure from bytes.
    See `BSDFSerializer` for details on extensions and options.
    )r0   r   )r'   r7   r8   r.   r   r   r   r     s    r   c                 K   st   t |fi |}t| trf| dr0tj| } t| d}||W  d   S 1 sZ0    Y  n
|| S dS )zLoad a (BSDF-encoded) structure from the given filename or file object.
    See `BSDFSerializer` for details on extensions and options.
    )z~/z~\rbN)	r0   r)   r*   
startswithospath
expanduserr   r   )r   r7   r8   r.   r   r   r   r   r   $  s    

*r   c                   @   s8   e Zd ZdZdZdZdd Zdd Zdd	 Zd
d Z	dS )rN   aC  Base class to implement BSDF extensions for special data types.

    Extension classes are provided to the BSDF serializer, which
    instantiates the class. That way, the extension can be somewhat dynamic:
    e.g. the NDArrayExtension exposes the ndarray class only when numpy
    is imported.

    A extension instance must have two attributes. These can be attributes of
    the class, or of the instance set in ``__init__()``:

    * name (str): the name by which encoded values will be identified.
    * cls (type): the type (or list of types) to match values with.
      This is optional, but it makes the encoder select extensions faster.

    Further, it needs 3 methods:

    * `match(serializer, value) -> bool`: return whether the extension can
      convert the given value. The default is ``isinstance(value, self.cls)``.
    * `encode(serializer, value) -> encoded_value`: the function to encode a
      value to more basic data types.
    * `decode(serializer, encoded_value) -> value`: the function to decode an
      encoded value back to its intended representation.

     r   c                 C   s   d| j tt| f S )Nz<BSDF extension %r at 0x%s>)rO   hexidr   r   r   r   __repr__[  s    zExtension.__repr__c                 C   s   t || jS r	   )r)   rS   r6   r.   r   r   r   r   r,   ^  s    zExtension.matchc                 C   s
   t  d S r	   NotImplementedErrorr   r   r   r   r"   a  s    zExtension.encodec                 C   s
   t  d S r	   r   r   r   r   r   r   d  s    zExtension.decodeN)
r   r   r   r   rO   rS   r   r,   r"   r   r   r   r   r   rN   >  s   rN   c                   @   s$   e Zd ZdZeZdd Zdd ZdS )ComplexExtensionr   c                 C   s   |j |jfS r	   )realimagr   r   r   r   r"   l  s    zComplexExtension.encodec                 C   s   t |d |d S )Nr   r   )complexr   r   r   r   r   o  s    zComplexExtension.decodeN)r   r   r   rO   r   rS   r"   r   r   r   r   r   r   h  s   r   c                   @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )NDArrayExtensionndarrayc                 C   s   dt jv rdd l}|j| _d S )Nnumpyr   )sysmodulesr   r   rS   )r6   npr   r   r   r:   v  s    
zNDArrayExtension.__init__c                 C   s   t |dot |dot |dS )Nshapedtypetobytes)r   r   r   r   r   r,   |  s    zNDArrayExtension.matchc                 C   s   t |jt|j| dS )N)r   r   data)rp   r   	text_typer   r   r   r   r   r   r"     s    zNDArrayExtension.encodec                 C   sH   zdd l }W n ty"   | Y S 0 |j|d |d d}|d |_|S )Nr   r   r   )r   r   )r   ImportErrorZ
frombufferr   )r6   r.   r   r   ar   r   r   r     s    

zNDArrayExtension.decodeN)r   r   r   rO   r:   r,   r"   r   r   r   r   r   r   s  s
   r   __main__)N)N)N)N)>r   
__future__r   r   r   r=   r   loggingr   r+   r   r   typesr<   ior   	getLoggerr   rQ   r   joinr   version_inforr   r
   r   r*   rn   r   rl   rL   rV   basicConfigunicode
basestringlongZ	ClassTyper   r   unpackr   r   r    r(   r/   objectr0   rw   rz   ru   r"   r   r   r   loadsdumpsrN   r   r   r3   Zbsdf_climainr   r   r   r   <module>   sj   


	
  gW ;




*
