o
    h                     @   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r[e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 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   P/var/www/html/scripts/venv/lib/python3.10/site-packages/imageio/plugins/_bsdf.py	<genexpr>0   s    r      c                 C   s   | dkr	t d| S t dd| S )z?Encode an unsigned integer into a variable sized blob of bytes.   <B<BQ   )spack)xr   r   r   lencodeJ   s   
r   c                 C   s4   t d| dd }|dkrt 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   s.   |dur| d}|  tt| | S | 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                   @   sn   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di | d S )Nr   )_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rt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)r5   compressionuse_checksumfloat64load_streaming	lazy_blobmr   r   r   r4      s   
	


zBsdfSerializer._parse_optionsc                 C   s   t |tr
t|tstd| }|j}t |tstdt|dks)t|dkr-td|| j	v r9t
d|  |j}|sAg }nt |ttfrK|}n|g}|D ]}t |ts[tdqP|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#   	NameErrorr0   loggerwarningclstuplelist
classtypesr!   r1   )r5   extension_classr8   rP   rT   clssr   r   r   r3      sB   



zBsdfSerializer.add_extensionc                 C   s^   t |ts	td|| jv r| j| t| j D ]}| j| d |kr,| j| qdS )z&Remove a converted by its unique name.rL   r   N)r(   r
   r?   r0   poprV   r1   keys)r5   rP   rT   r   r   r   remove_extension   s   

zBsdfSerializer.remove_extensionc                 C   s  t }|du r||d| dS |du r||d| dS |du r,||d| dS t|tr[d|  kr;dkrLn n||d	|td
|  dS ||d|td|  dS t|tr| jrr||d|td|  dS ||d|td|  dS t|tr|d}||d|t	t
|  || dS t|ttfr||d|t	t
|  |D ]
}| |||d qdS t|tr||d|t	t
|  | D ].\}}tr| sJ nt|sJ |d}	|t	t
|	 ||	 | |||d qdS t|tr+||d| t|| j| jd}
|
| dS t|tr@||d| || dS t|tr|jdkrPtdt|tre||d|tddd  ntdt
|dkrttd|| ||| j| j dS |durtd| | j !|j"d}|du r| j# D ]\}}|$| |r||jf} nqd}|dur|\}}| ||| ||| dS d}t||j"j% ) zMain encoder function.N   vT   yF   ni i     hh   i<q   d<d   f<fr       s   l   m   b)rF   rG   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   floatrC   unicode_typesr!   r   r#   rV   rU   _encodedictitemsPY3isidentifierr.   bytesBlobr@   rB   _to_file
BaseStreammode
ValueError
ListStreamr?   append	_activate_decoder1   r=   	__class__r0   r+   __name__)r5   r   valuestreamsr%   r   r&   vkeyname_bblobexrP   cext_id2extension_encodetr   r   r   rr      s   












zBsdfSerializer._encodec                    sn    d}| }|st ||kr%td  dd }  |d}nd}|dkr/d}nf|dkr7d}n^|d	kr?d
}nV|dkrOtd  dd }nF|dkr_td  dd }n6|dkrotd  dd }n&|dkrtd  dd }n|dkrtd  dd }|dkrtd  dd }  |d}n|dkrtd  dd }|dkr|dk}td  dd }jrt|r|nd}| jj	 n|r fddt
|D }ng }z
	 |	  q ty   Y nw |dkrtd  dd } fddt
|D }nz|dkrtt }td  dd }|dkr<td  dd }t
|D ]2}	td  dd }
|
dkr[td  dd }
|
dksbJ   |
d}	 ||< q@n!|d krjrt df}nt d
f}| }ntd!| |durj|d}|dur||}|S td"|  |S )#zMain decoder function.r   r   r   r    Nr]   r^   Tr_   Fr`   z<hr   rb   rc   r   rf   rg      rd   re   rh   r   r   ri      rc                       g | ]}  qS r   r   r   r   r5   r   r   
<listcomp>r      z*BsdfSerializer._decode.<locals>.<listcomp>c                    r   r   r   r   r   r   r   r   ~  r   rj   rk   zParse error %rz'BSDF warning: no extension found for %r)r   r>   EOFErrorr   decoderD   r}   r   rr   r   ranger~   rs   rE   rx   	get_bytesRuntimeErrorr0   r=   rR   rS   )r5   r   charr   r   r%   r   n_sclosedr   n_namerP   r   r8   r   r   r   r   D  s   









zBsdfSerializer._decodec                 C   s   t  }| || | S )zSave the given object to bytes.)r   savegetvalue)r5   obr   r   r   r   r!     s   zBsdfSerializer.encodec                 C   s|   | d | tdtd  | tdtd  g }| |||d t|dkr:|d }|j| kr<tddS 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.)	rn   structpackVERSIONrr   r#   
_start_postellr|   )r5   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)r5   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r9d}t|t|f |td krJd	}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__rR   rS   r   )r5   r   f4major_versionminor_versionfile_versionr   r   r   r   r     s   

zBsdfSerializer.loadr	   )r   FTFF)r   
__module____qualname____doc__r9   r4   r3   r\   rr   r   r!   r   r   r   r   r   r   r   r/   t   s"    

+
[Zr/   c                   @   s.   e Zd ZdZd
ddZdd Zedd Zd	S )rz   zBase class for streams.rl   c                 C   sR   d| _ d| _t|tr|| _d}n|dkrd| _|dv sJ || _d | _d| _d S )Nr   r   rl   )r   rl   )_i_countr(   int_mode_fr   )r5   r{   r   r   r   r9     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   rr   r   )r5   fileencode_funcdecode_funcr   r   r   r     s   

zBaseStream._activatec                 C      | j S )z$The mode of this stream: 'r' or 'w'.)r   r5   r   r   r   r{        zBaseStream.modeN)rl   )r   r   r   r   r9   r   propertyr{   r   r   r   r   rz     s    
rz   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 )r}   zjA streamable list object used for writing or reading.
    In read mode, it can also be iterated over.
    c                 C   r   )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   r   )z/The current index of the element to read/write.)r   r   r   r   r   index  r   zListStream.indexc                 C   sj   | j | jkr
td| jdu rtd| jjrt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   rr   )r5   itemr   r   r   r~     s   
zListStream.appendFc                 C   s   | j | jkr
td| jdu rtd| jjrtd| j }| j| jd d  | jt	d|r4d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   rn   r   )r5   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r8| j| jkr+t |  jd7  _| | jS z| | j}|  jd7  _|W S  tyV   | j| _t w )	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   )r5   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   r}     s    


r}   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 )rx   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rd | _| ||| _|| _| j| | _|| _d S t |t	rCt
|dkrCt|d drC|\| _}d | _| | j| d| _d S td)Nr   r   r   FzWrong argument to create Blob.)r(   rw   r   _from_bytes
compressedrF   	used_sizeallocated_sizerG   rU   r#   hasattr
_from_file	_modifiedr?   )r5   r&   rF   
extra_sizerG   
allow_seekr   r   r   r9   X  s   

$

zBlob.__init__c                 C   sZ   |dkr|}n|dkrt |d}n|dkrt|d}nJ 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   )r5   r   rF   r   r   r   r   r   g  s   

zBlob._from_bytesc                 C   s8  | j dkr%| jdkr%|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rd	| 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   rF   rn   r   r   r   r   rG   hashlibmd5r   digestr   )r5   r   	alignmentr   r   r   ry   v  s$   

zBlob._to_filec           
      C   sf  t d|dd }|dkrt d|dd }t d|dd }|dkr0t d|dd }t d|dd }|dkrHt d|dd }t d|dd }t d|dd }|rc|d}t d|dd }	||	 |r| | _| j| | _|| j|  nd| _d| _||| _|||  |	| _|| _|r|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   rF   rG   r   r   r   )
r5   r   r   r   r   r   rF   has_checksumchecksumr   r   r   r   r     s:   



zBlob._from_filec                 C   sT   | j du r	td|dk r| j| }|dk s|| 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   )r5   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   rF   r   r   r#   r   r   rn   )r5   r&   r   r   r   rn     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   rF   r   r   r   r   )r5   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r)|}|S | jdkr5t|}|S | jdkrAt	|}|S t
d| j )z&Get the contents of the blob as bytes.Nr   r   r   zInvalid compression %i)r   r   r   r   r   r   rF   r;   
decompressr<   r   )r5   r   r   r   r   r   r   r     s    







zBlob.get_bytesc                 C   sb   | j r-| jr/| d | j| j}| j| j| j d d  | jt	
|  dS dS dS )zZReset the blob's checksum if present. Call this after modifying
        the data.
        r   r   r   N)rG   r   r   r   r   r   r   r   rn   r   r   r   )r5   r   r   r   r   update_checksum  s   
zBlob.update_checksumN)r   r   F)r   r   r   r   r9   r   ry   r   r   r   rn   r   r   r   r   r   r   r   rx   N  s    
	'rx   c                 K      t |fi |}|| S )zrSave (BSDF-encode) the given object to bytes.
    See `BSDFSerializer` for details on extensions and options.
    )r/   r!   )r   r6   r7   r-   r   r   r   r!        
r!   c                 K   s`   t |fi |}t| tr*t| d}|||W  d   S 1 s#w   Y  dS || |S )zSave (BSDF-encode) the given object to the given filename or
    file object. See` BSDFSerializer` for details on extensions and options.
    wbN)r/   r(   r)   openr   )r   r   r6   r7   r-   fpr   r   r   r     s   

$r   c                 K   r   )zpLoad a (BSDF-encoded) structure from bytes.
    See `BSDFSerializer` for details on extensions and options.
    )r/   r   )r&   r6   r7   r-   r   r   r   r     r   r   c                 K   sr   t |fi |}t| tr4| drtj| } t| d}||W  d   S 1 s-w   Y  dS || S )zLoad a (BSDF-encoded) structure from the given filename or file object.
    See `BSDFSerializer` for details on extensions and options.
    )z~/z~\rbN)	r/   r(   r)   
startswithospath
expanduserr   r   )r   r6   r7   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 )rO   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>)rP   hexidr   r   r   r   __repr__[  s   zExtension.__repr__c                 C   s   t || jS r	   )r(   rT   r5   r-   r   r   r   r   r+   ^     zExtension.matchc                 C      t  r	   NotImplementedErrorr   r   r   r   r!   a     zExtension.encodec                 C   r   r	   r   r   r   r   r   r   d  r   zExtension.decodeN)
r   r   r   r   rP   rT   r   r+   r!   r   r   r   r   r   rO   >  s    rO   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  r   zComplexExtension.encodec                 C   s   t |d |d S )Nr   r   )complexr   r   r   r   r   o  s   zComplexExtension.decodeN)r   r   r   rP   r   rT   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 d S )Nnumpyr   )sysmodulesr  r  rT   )r5   npr   r   r   r9   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)rs   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 w |j|d |d d}|d |_|S )Nr   r	  r  )r  r  )r  ImportError
frombufferr  )r5   r-   r   r  ar   r   r   r     s   
zNDArrayExtension.decodeN)r   r   r   rP   r9   r+   r!   r   r   r   r   r   r   s  s    r   __main__r	   )>r   
__future__r   r   r   r<   r   loggingr   r*   r   r  typesr;   ior   	getLoggerr   rR   r   joinr   version_inforu   r
   r
  r)   rq   r   ro   rM   rW   basicConfigunicode
basestringlong	ClassTyper   r   unpackr   r   r   r'   r.   objectr/   rz   r}   rx   r!   r   r   r   loadsdumpsrO   r   r   r2   bsdf_climainr   r   r   r   <module>   sn   


	
  gW 
;



*