U
    ߦwh                  
   @   s  d Z dZddlZddlZddlZddlmZ ddlmZ ddl	m
Z
mZmZmZmZmZmZmZmZmZmZ ddlmZmZmZ dd	lmZmZmZmZmZmZm Z m!Z!m"Z" dd
l#m$Z$m%Z%m&Z& ddl#m'Z( ddl#m)Z* ddl#m+Z, ddl#m-Z. ddl/m0Z0m1Z1m2Z2 ddl3m4Z4m5Z5m6Z6m7Z7m8Z8m9Z9m:Z:m;Z;m<Z<m=Z= ddl>m?Z? ddl@mAZAmBZBmCZCmDZDmEZE ddlmFZFmGZG ejHdkrddl	mIZI nddlJmIZI eKeLZMeNdZOG dd dee
 e;ZPG dd dee
e
f e;ZQG dd deQZRe
dddd ZSG d!d" d"eQZTG d#d$ d$eTZUG d%d& d&eTZVG d'd( d(eUZWd0eee edeXeeX eeYeXf f ee;eYeXeWf d)d*d+ZZG d,d- d-eRZ[G d.d/ d/eRZ\dS )1zMathieu Fenniakzbiziqe@mathieu.fenniak.net    N)BytesIO)ceil)AnyCallableDictIterableListOptionalSequenceSetTupleUnioncast   )PdfReaderProtocolPdfWriterProtocolXmpInformationProtocol)	WHITESPACES
StreamTypedeprecation_no_replacementdeprecation_with_replacementlogger_warningread_non_whitespaceread_until_regexread_until_whitespaceskip_over_comment)CheckboxRadioButtonAttributesFieldDictionaryAttributesOutlineFontFlag)FilterTypes)StreamAttributes)TypArguments)TypFitArguments)STREAM_TRUNCATED_PREMATURELYPdfReadErrorPdfStreamError   )
BooleanObjectByteStringObjectFloatObjectIndirectObject
NameObject
NullObjectNumberObject	PdfObjectTextStringObjectis_null_or_none)Fit)extract_inline_A85extract_inline_AHxextract_inline_DCTextract_inline_defaultextract_inline_RL)read_hex_string_from_streamread_string_from_stream)      )Selfs   [+-]?(\d+)\s+(\d+)\s+R[^a-zA-Z]c                   @   s   e Zd Zed dddZdeeeeee	e
f   d dddZe
d	d
dZee d	ddZeee dddZed dddZeedddZeedddZdeede	ef ddddZed eee ede	ee	 ee
e	f f d dddZdS )!ArrayObjectpdf_destreturnc                 C   sJ   t d| t |d}| D ]*}t|dr:||| q|| q|S )Nr<   F	replicate)r   _reference_cloner<   hasattrappendr@   )selfr>   arrdata rG   B/tmp/pip-unpacked-wheel-r8zeli8p/pypdf/generic/_data_structures.pyr@   i   s    
zArrayObject.replicateFrG   r>   force_duplicateignore_fieldsr?   c                 C   s   z| j j|kr|s| W S W n tk
r.   Y nX td| t ||}| D ]^}t|tr~|||||||}|	|j  qJt
|dr|	|||| qJ|	| qJ|S )Clone object into pdf_dest.r<   clone)indirect_referencepdf	Exceptionr   rA   r<   
isinstanceStreamObjectrM   rC   rB   )rD   r>   rJ   rK   rE   rF   duprG   rG   rH   rM   x   s*    


zArrayObject.cloner?   c                 C   s   t | jtdd | D fS )q
        Used to detect modified object.

        Returns:
            Hash considering type and value.

        c                 s   s   | ]}|  V  qd S Nhash_bin.0xrG   rG   rH   	<genexpr>   s     z'ArrayObject.hash_bin.<locals>.<genexpr>)hash	__class__tuplerD   rG   rG   rH   rX      s    zArrayObject.hash_binc                 C   s   t | S )z:Emulate DictionaryObject.items for a list (index, object).)	enumerater`   rG   rG   rH   items   s    zArrayObject.items)lstr?   c                 C   sr   t |tttfrn\t |tr$|g}nJt |trR|d dkrFt|g}qnt|g}nt |trht	|g}n|g}|S )Nr   /)
rQ   listr_   setr.   strr+   r/   bytesr(   rD   rc   rG   rG   rH   _to_lst   s    


zArrayObject._to_lstc                 C   s   t | }|| | |S )a  
        Allow extension by adding list or add one element only

        Args:
            lst: any list, tuples are extended the list.
            other types(numbers,...) will be appended.
            if str is passed it will be converted into TextStringObject
            or NameObject (if starting with "/")
            if bytes is passed it will be converted into ByteStringObject

        Returns:
            ArrayObject with all elements

        )r<   extendrj   )rD   rc   temprG   rG   rH   __add__   s    zArrayObject.__add__c                 C   s   |  | | | S )a  
         Allow extension by adding list or add one element only

        Args:
            lst: any list, tuples are extended the list.
            other types(numbers,...) will be appended.
            if str is passed it will be converted into TextStringObject
            or NameObject (if starting with "/")
            if bytes is passed it will be converted into ByteStringObject

        )rk   rj   ri   rG   rG   rH   __iadd__   s    zArrayObject.__iadd__c              	   C   s>   |  |D ].}z| |}| |= W q
 tk
r6   Y q
X q
| S )zAllow to remove items)rj   index
ValueError)rD   rc   r[   rG   rG   rH   __isub__   s    

zArrayObject.__isub__Nstreamencryption_keyr?   c                 C   sH   |d k	rt dd |d | D ]}|d || q |d d S )N/the encryption_key parameter of write_to_stream5.0.0   [    s    ])r   writewrite_to_stream)rD   rs   rt   rF   rG   rG   rH   rz      s     

zArrayObject.write_to_streamrs   rO   forced_encodingr?   c                 C   s   t  }| d}|dkr td| d}| r>| d}q*|dkrHq|dkrf| dd t|  q | dd | d}|dkrq| dd |t| || q |S )Nr&   rw   zCould not read array       %   ])r<   readr$   isspaceseekr   rC   read_object)rs   rO   r|   rE   tmptokZ
peek_aheadrG   rG   rH   read_from_stream   s(    


zArrayObject.read_from_stream)FrG   )N)N)__name__
__module____qualname__r   r@   boolr	   r
   r   rg   intrM   rX   r   r   rb   r   rj   rm   r;   rn   rq   r   rh   rz   staticmethodr   r   r   rG   rG   rG   rH   r<   h   s>     
   r<   c                   @   sL  e Zd Zed dddZd%eeeeee	e
f   d dddZd eeeeee	e
f   eee
e
f  d	d
ddZe
dddZeedddZd&e	eedddZeeedddZd'eee edddZeedddZeee dddZd(eed	e	ef d	dd d!Zed)eee ed	e	ee	 e e
e	f f d d"d#d$Z!d	S )*DictionaryObjectr=   c                 C   sP   t d| |  |d}|  D ]*\}}t|dr<||n||||< q |S )Nr   Fr@   )r   rA   r^   rb   rB   r@   )rD   r>   d__kvrG   rG   rH   r@     s    zDictionaryObject.replicateFrG   rI   c                 C   s   z| j j|kr|s| W S W n tk
r.   Y nX t }td| |  ||}|dkrZg }t| dkr||	| |||| |S )rL   r   Nr   )
rN   rO   rP   rf   r   rA   r^   lenkeys_clonerD   r>   rJ   rK   visitedr   rG   rG   rH   rM     s    
zDictionaryObject.cloneNsrcr>   rJ   rK   r   r?   c              
      s  d} dk	st t  |t k rlt | trbtt | dkrR |=  |= q |  d8  < |d7 }qt fdddD r.t  dD ]}|D ]}g }	|kr|| krt|trt| t	r
dddks$tt	| 
dddks$
ddtt	| 
ddkrtd	| }
| }|
dk	rtd	|
|
 ||}|jdk	r|jj}|jj}||f|krd}
q|||f |	|
|f |dk	st |j|t|< |}z"|
krd}
ntd	|
| }
W n tk
r   d}
Y nX q6|	D ]\}}|||| | qqq D ]\}}| kr6t|trt|d
sfd|_||| }|jdk	st |j| ||< n0|| kr6t|dr||| n|| t|< q6dS )z
        Update the object from src.

        Args:
            src: "DictionaryObject":
            pdf_dest:
            force_duplicate:
            ignore_fields:

        r   Nr&   c                 3   s   | ]}| ko~|ko~t |to~t | to~d ddkp~tt| d ddkp~d dtt| d dkV  qdS )/TypeN)rQ   raw_getr*   r   getr   )rZ   fieldrK   r   rG   rH   r\   U  s   
z*DictionaryObject._clone.<locals>.<genexpr>)/Next/Prev/N/V))r   r   )r   r   r   r   rN   rM   )AssertionErrorre   r   rQ   r   r   anyr   r*   r   r   rA   r^   rN   idnum
generationaddrC   r+   rP   r   rb   rR   rB   rM   )rD   r   r>   rJ   rK   r   r[   rc   r   objsZcur_objZprev_objZclonr   r   scr   vvrG   r   rH   r   5  s    



	

 
  
    

zDictionaryObject._clonerT   c                 C   s    t | jtdd |  D fS )rU   c                 s   s   | ]\}}||  fV  qd S rV   rW   )rZ   r   r   rG   rG   rH   r\     s     z,DictionaryObject.hash_bin.<locals>.<genexpr>)r]   r^   r_   rb   r`   rG   rG   rH   rX     s    zDictionaryObject.hash_bin)keyr?   c                 C   s   t | |S rV   )dict__getitem__rD   r   rG   rG   rH   r     s    zDictionaryObject.raw_get)r   defaultr?   c                 C   s^   || kr| | S zd| kr |W S t dW n. t k
rX   td| d  || Y S X dS )a>  
        Returns the value of a key or from the parent if not found.
        If not found returns default.

        Args:
            key: string identifying the field to return

            default: default value to return

        Returns:
            Current key or inherited one, otherwise default value.

        /ParentzNot presentr   N)KeyErrorr   
get_objectget_inherited)rD   r   r   rG   rG   rH   r     s     zDictionaryObject.get_inherited)r   valuer?   c                 C   s2   t |tstdt |ts$tdt| ||S NzKey must be a PdfObjectzValue must be a PdfObject)rQ   r.   rp   r   __setitem__rD   r   r   rG   rG   rH   r     s
    

zDictionaryObject.__setitem__c                 C   s2   t |tstdt |ts$tdt| ||S r   )rQ   r.   rp   r   
setdefaultr   rG   rG   rH   r     s
    

zDictionaryObject.setdefaultc                 C   s   t | | S rV   )r   r   r   r   rG   rG   rH   r     s    zDictionaryObject.__getitem__c                 C   s^   ddl m} | dd}t|r$dS |dk	s4td| }t||sZ||}|| td< |S )u  
        Retrieve XMP (Extensible Metadata Platform) data relevant to the this
        object, if available.

        See Table 347 — Additional entries in a metadata stream dictionary.

        Returns:
          Returns a :class:`~pypdf.xmp.XmpInformation` instance
          that can be used to access XMP metadata from the document. Can also
          return None if no metadata was found on the document root.

        r   )XmpInformationz	/MetadataNmypy)xmpr   r   r0   r   r   rQ   r+   )rD   r   metadatarG   rG   rH   xmp_metadata  s    
zDictionaryObject.xmp_metadatarr   c                 C   s   |d k	rt dd |d |  D ]X\}}t|dkrR|d dkrR|d dkrRq$||| |d || |d	 q$|d
 d S )Nru   rv      <<
r   r&   %r   rx      
   >>)r   ry   rb   r   rz   )rD   rs   rt   r   r   rG   rG   rH   rz     s     
$

z DictionaryObject.write_to_streamr{   c              
      s|  t t tt  tt ddd tttd fdd}| d}|dkrZtd	t|   d
i }t	| }|dkrpq^|dkr| 
dd t|  q^|stt|dkr| d q(| 
dd zz8t| |}t|trW W q(t|tstd|W nP tk
rF } z0|d k	r|jr t| t W Y W q^W 5 d }~X Y nX t	| }| 
dd t| ||}	W nh tk
r } zH|d k	r|jrt| t| t t }
|
| |
 W Y S d }~X Y nX ||s|	||< q^dt|   d| }|d k	r|jrt|t|t q^|  }t	| }|dkrH| ddkrH| d}|dkrt| d}q\|dkrtd|dkr| ddkr| 
dd tj|kr|d k	r|jrtdtd|   t td|ttj< |tj }t|tr>|  }|d k	s(td||}| 
|d |d krLd}|  }|dkrn| ||d< nt | t!"d |d< t	| }| d!}|| d krT|  }| 
d"d | d#}|d kr|d d d |d< nf|d k	r|js| 
|d || ||d< |  }n0| 
|d td$t|   d%|d&|d'n| 
|d d|krht#$|S t }
|
| |
S )(N)pp1rem_gensrO   r?   c              	      s`   }|D ]R}|j | }z. fdd| D }|rBt|f| }W q tk
rX   Y qX q|S )Nc                    s(   g | ] } |  k rkrn q|qS rG   rG   rY   r   r   rG   rH   
<listcomp>  s
      
  zODictionaryObject.read_from_stream.<locals>.get_next_obj_pos.<locals>.<listcomp>)xrefvaluesminrp   )r   r   r   rO   outgenlocr   rG   r   rH   get_next_obj_pos  s    
z;DictionaryObject.read_from_stream.<locals>.get_next_obj_pos)rs   rO   r?   c                    sz    |   dt|j|d }|   }| ||    }|d}|dk rXtd| d| || d  |d |d  S )Nl        r&   	   endstreamr   z6Unable to find 'endstream' marker for obj starting at .	   )tellre   r   r   findr$   r   )rs   rO   Zeoncurrrwr   r   rG   rH   read_unsized_from_stream  s    

zCDictionaryObject.read_from_stream.<locals>.read_unsized_from_streamr      <<zDictionary read error at byte z: stream must begin with '<<'    r~   r   r&      >z)Expecting a NameObject for key but found z+Multiple definitions in dictionary at byte z	 for key    s   s   treamrx   )r      z)Stream data must be followed by a newliner   r   zStream length not definedzStream length not defined @pos=r   r   __streamdata__r      ir   z7Unable to find 'endstream' marker after stream at byte z (nd='z', end='z').)%r   r   r   r   rh   r   r$   hexr   r   r   r   r%   r#   r   rQ   r,   r+   strictr   __repr__r   rP   r   updater   SALENGTHr-   r*   r   r   r   recompilerR   initialize_from_dictionary)rs   rO   r|   r   r   rF   r   r   excr   retvalmsgposr   eollengthtZpstarteZndstreamendrG   r   rH   r     s        









 



 






z!DictionaryObject.read_from_stream)FrG   )N)N)N)N)"r   r   r   r   r@   r   r	   r
   r   rg   r   rM   r   r   r   rX   r   r   r   r   r   r.   r   propertyr   r   r   rh   rz   r   r   r   r   r   rG   rG   rG   rH   r     sP     q   r   c                   @   s   e Zd Zd"ee ddddZedddZeddd	Z	e
e dd
dZeeddddZeded f eddddZeded f eddddZd#eeeeedef  edddZeeeeddddZeddddZddddZddd d!ZdS )$
TreeObjectN)dctr?   c                 C   s   t |  |r| | d S rV   )r   __init__r   )rD   r   rG   rG   rH   r     s    
zTreeObject.__init__rT   c                 C   s   d| kS )N/FirstrG   r`   rG   rG   rH   has_children  s    zTreeObject.has_childrenc                 C   s   |   S rV   )childrenr`   rG   rG   rH   __iter__  s    zTreeObject.__iter__c                 c   sb   |   sd S | td }| }|V  || td kr:d S |td}t|rTd S | }q d S )Nr   /Lastr   )r   r+   r   r   r0   )rD   Z	child_refchildrG   rG   rH   r     s    zTreeObject.children)r   rO   r?   c                 C   s   |  |d | d S rV   )insert_child)rD   r   rO   rG   rG   rH   	add_child  s    zTreeObject.add_child)parentnr?   c                 C   sr   t |rd S |d k	stdtd| }d|krnttdtt|td | |td< | |	dd | d S )Nr   r   /Countr   r   )
r0   r   r   r   r-   maxr   r+   inc_parent_counter_defaultr   )rD   r   r   rG   rG   rH   r    s    z%TreeObject.inc_parent_counter_defaultc                 C   s   t |rd S |d k	stdtd| }|dddk}tt|dd}|dk r\t|}t|| |rldnd |td< |sd S | 	|d	d | d S )
Nr   r   z
/%is_open%Tr   r   r&   r   r   )
r0   r   r   r   r   r   absr-   r+   inc_parent_counter_outline)rD   r   r   Zopnr   rG   rG   rH   r    s     z%TreeObject.inc_parent_counter_outline.)r   beforerO   inc_parent_counterr?   c                 C   s  |d kr| j }| }|j}d| kr|| td< td| td< || td< | j|td< || |dd d|krz|d= d|kr|d= |S td	| d }|j|krd|krtd
|d }qtd
||td< |j|td< | j|td< d|kr|d= || td< || |dd |S qz8t|d ts4t	||d td< |d |td< W n t
k
rr   |d= Y nX ||td< ||td< | j|td< || |dd |S )Nr   r   r   r   r   r&   r   r   r   r   )r  r   rN   r+   r-   r   r   rQ   r   r   rP   )rD   r   r  rO   r  	child_objprevrG   rG   rH   r     sL    zTreeObject.insert_child)r  prev_refcurlastr?   c                 C   s   | tdd}|dkr|rX| }|td= || td< t| td d | td< qtd| td< | td= td| kr| td= nd|r| }||td< ||td< n"||kst|td= || td< t| td d | td< dS )	z
        Adjust the pointers of the linked list and tree node count.

        Args:
            prev:
            prev_ref:
            cur:
            last:

        r   Nr   r   r   r&   r   r   )r   r+   r   r-   r   )rD   r  r  r	  r
  Znext_refZnext_objrG   rG   rH   _remove_node_from_tree  s*    


z!TreeObject._remove_node_from_tree)r   r?   c           
      C   s   |  }|j}td|kr"td|td | kr:tdd}d }d }| td }|  }| td }|  }	|d k	r||kr| ||||	 d}q|}|}td|kr|td }|  }qnd }d }qn|std	t| d S )
Nr   /Removed child does not appear to be a tree itemz*Removed child is not a member of this treeFr   r   Tr   z"Removal couldn't find item in tree)r   rN   r+   rp   r  _reset_node_tree_relationship)
rD   r   r  foundr  r  Zcur_refr	  Zlast_refr
  rG   rG   rH   remove_childG  s8    
zTreeObject.remove_childc                 C   s,   t d| krtdtd| d |  dS )z)Remove the object from the tree it is in.r   r  r   N)r+   rp   r   r  r`   rG   rG   rH   remove_from_treel  s    zTreeObject.remove_from_treec                 C   s`   | D ]}|  }t| qtd| kr0| td= td| krF| td= td| kr\| td= d S )Nr   r   r   )r   r  r+   )rD   r   r  rG   rG   rH   
empty_treer  s    


zTreeObject.empty_tree)N)N)r   r   r   r	   r   r   r   r   r   r   r   r   r   r   r   r*   r   r  r  r   r   r  r  r  r  rG   rG   rG   rH   r     s<      3   +%r   )r  r?   c                 C   s:   | t d= t d| kr | t d= t d| kr6| t d= dS )z
    Call this after a node has been removed from a tree.

    This resets the nodes attributes in respect to that tree.

    Args:
        child_obj:

    r   r   r   N)r+   )r  rG   rG   rH   r    s
    


r  c                       s"  e Zd ZddddZed dddZeeeee	e
eef   eeeef  dd fd	d
Zed fddZedddZeddddZed fddZd#ee
deef ddddZeeeef ddddZeeeef e
d dddZd$edddd Zedd!d"Z  ZS )%rR   NrT   c                 C   s   d| _ d | _d S Nr}   )_datadecoded_selfr`   rG   rG   rH   r     s    zStreamObject.__init__r=   c                 C   s   t d| |  |d}| j|_z,| j}|d kr8d | _nt d||| _W n tk
r`   Y nX |  D ]*\}}t|dr||n||||< qj|S )NrR   FDecodedStreamObjectr@   )	r   rA   r^   r  r  r@   rP   rb   rB   rD   r>   r   r  r   r   rG   rG   rH   r@     s&     
zStreamObject.replicater   c                    sr   t d|j| _z6t d|j}|dkr,d| _nt d||||| _W n tk
rX   Y nX t ||||| dS )
        Update the object from src.

        Args:
            src:
            pdf_dest:
            force_duplicate:
            ignore_fields:

        rR   Nr  )r   r  r  rM   rP   superr   )rD   r   r>   rJ   rK   r   r  r^   rG   rH   r     s    
zStreamObject._clonec                    s   t t  | jfS )rU   )r]   r  rX   r  r`   r  rG   rH   rX     s    	zStreamObject.hash_binc                 C   s   | j S rV   r  r`   rG   rG   rH   get_data  s    zStreamObject.get_datarF   r?   c                 C   s
   || _ d S rV   r  rD   rF   rG   rG   rH   set_data  s    zStreamObject.set_datac                    s   t   }||  7 }|S rV   )r  hash_value_datar  r  r  rG   rH   r    s    
zStreamObject.hash_value_datarr   c                 C   sb   |d k	rt dd tt| j| ttj< t| | | tj= |	d |	| j |	d d S )Nru   rv   s   
stream
s
   
endstream)
r   r-   r   r  r+   r   r   r   rz   ry   rD   rs   rt   rG   rG   rH   rz     s     
zStreamObject.write_to_streamc                 C   s   t ddd d S )NinitializeFromDictionaryr   rv   )r   )rF   rG   rG   rH   r!    s
      z%StreamObject.initializeFromDictionary)EncodedStreamObjectr  c                 C   sH   t j| krt }nt }| d |_| d= t j| kr:| t j= ||  |S )Nr   )r   FILTERr"  r  r  r   r   )rF   r   rG   rG   rH   r     s    



z'StreamObject.initialize_from_dictionaryr   r"  )levelr?   c              	   C   s  ddl m} tj| kr| tj }t|trtttjf|}z tt	 f| 
tjt }W q tk
r   tt	 | 
tjt g}Y qX qtttj|g}tt	 | 
tjt	 g}nttj}d }t }||  ||ttj< |d k	r||ttj< || j||_|S )Nr   FlateDecode)filtersr&  r   r#  rQ   r<   r+   FTFLATE_DECODEr,   r   DECODE_PARMS	TypeErrorr"  r   encoder  )rD   r$  r&  fparamsr   rG   rG   rH   flate_encode  s4    





zStreamObject.flate_encodec                 C   sx   ddl m} | dddkrZz| j d}W n" tk
rN   |   d}Y nX t|t || \}}}|dkrtdS |S )	a~  
        Try to decode the stream object as an image

        Returns:
            a PIL image if proper decoding has been found
        Raises:
            Exception: (any)during decoding to to invalid object or
                errors during decoding will be reported
                It is recommended to catch exceptions to prevent
                stops in your program.

        r   )_xobj_to_imagez/Subtype z/Imagez does not seem to be an Imagez$ object does not seem to be an ImageN)r'  r0  r   rN   AttributeErrorr   r   r   )rD   r0  r   	extensionZbyte_streamimgrG   rG   rH   decode_as_image(  s    
zStreamObject.decode_as_image)N)r   )r   r   r   r   r   r@   r   r   r	   r
   r   rg   r   r   r   r   rX   rh   r  r  r  r   rz   r   r   r   r!  r   r/  r5  __classcell__rG   rG   r  rH   rR     s:      
 rR   c                   @   s   e Zd ZdS )r  N)r   r   r   rG   rG   rG   rH   r  C  s   r  c                       s@   e Zd ZddddZedddZedd fdd	Z  ZS )
r"  NrT   c                 C   s
   d | _ d S rV   )r  r`   rG   rG   rH   r   H  s    zEncodedStreamObject.__init__c                 C   sp   ddl m} | jd k	r | j S t }|||  |  D ]$\}}|tjtj	tj
fkr<|||< q<|| _| S )Nr   )decode_stream_data)r'  r7  r  r  r  r  rb   r   r   r#  r*  )rD   r7  decodedr   r   rG   rG   rH   r  L  s    


zEncodedStreamObject.get_datar  c                    s   ddl m} | tjdtjtjgfkr~t|ts:t	d| j
d krL|   | j
d k	s^td| j
| t || ntdd S )Nr   r%  r1  zData must be bytesr   zJStreams encoded with a filter different from FlateDecode are not supported)r'  r&  r   r   r#  r(  r)  rQ   rh   r+  r  r  r   r  r  r,  r$   )rD   rF   r&  r  rG   rH   r  ]  s    

zEncodedStreamObject.set_data)r   r   r   r   rh   r  r  r6  rG   rG   r  rH   r"  G  s   r"  c                
       sn  e Zd ZdZd%eeedeee ee	ef f dd fddZ
ed dddZd&eeeeeee	f   d dddZeeeeeeee	f   eee	e	f  dd fddZeddddZeeeef dddZedddZedd fddZeeeeef  dddZejeeeef  ddddZddd d!Zd'eedeef dd" fd#d$Z  Z S )(ContentStreama  
    In order to be fast, this data structure can contain either:

    * raw data in ._data
    * parsed stream operations in ._operations.

    At any time, ContentStream object can either have both of those fields defined,
    or one field defined and the other set to None.

    These fields are "rebuilt" lazily, when accessed:

    * when .get_data() is called, if ._data is None, it is rebuilt from ._operations.
    * when .operations is called, if ._operations is None, it is rebuilt from ._data.

    Conversely, these fields can be invalidated:

    * when .set_data() is called, ._operations is set to None.
    * when .operations is set, ._data is set to None.
    Nr{   c                    s   || _ g | _|d kr"t d n| }t|trd}|D ]h}| }t|trTq<t|tsxt	dt
|j dt n|| 7 }t|dks|d dkr<|d7 }q<t t| n | }|d k	stt | || _d S )Nr}   zExpected StreamObject, got z instead. Data might be wrong.r   r   r   )rO   _operationsr  r  r   rQ   r<   r,   rR   r   typer   r  r   rh   r   r|   )rD   rs   rO   r|   rF   r   Z
s_resolvedZstream_datar  rG   rH   r     s0    



zContentStream.__init__r=   c                 C   s   t d| | d d |d}| j|_z,| j}|d kr<d | _nt d||| _W n tk
rd   Y nX |  D ]*\}}t|dr||n||||< qn|S )Nr9  Fr  r@   )r   rA   r^   r  r  r@   rP   rb   rB   r  rO   re   r:  r|   r  rG   rG   rH   r@     s0     
    zContentStream.replicateFrG   rI   c                 C   st   z| j j|kr|s| W S W n tk
r.   Y nX t }td| | dd||}|dkr^g }|| |||| |S )z
        Clone object into pdf_dest.

        Args:
            pdf_dest:
            force_duplicate:
            ignore_fields:

        Returns:
            The cloned ContentStream

        r9  N)rN   rO   rP   rf   r   rA   r^   r   r   rG   rG   rH   rM     s$    

  zContentStream.cloner   c                    s6   t d|}t |j || _t|j| _|j| _dS )r  r9  N)r   r  r  r  rO   re   r:  r|   )rD   r   r>   rJ   rK   r   Zsrc_csr  rG   rH   r     s
    
zContentStream._clone)rs   r?   c                 C   s   | dd g }t|}|dkr"q| dd | s>|dkrt|tj}|dkrz|g ks^t| |}| j	|df q| j	||f g }q|dkr|d	kr|
d}qq|	t|d | j qd S )
Nr   )r}   r   r   r&   )   '   "   BI   INLINE IMAGEr~   )r   r   r}   )r   r   isalphar   r+   Zdelimiter_patternr   _read_inline_imager:  rC   r   r   r|   )rD   rs   operandspeekoperatoriirG   rG   rH   _parse_content_stream  s$    
z#ContentStream._parse_content_streamc                 C   s  t  }t|}|dd |dkr$qZt|| j}t|}|dd t|| j}|||< q|d}|d d dksxt|d|dd	}| }t	|t
r|d
 }d|ksd|krt|}	n*d|ksd|krt|}	nd|ksd|krt|}	nd|ksd|krt|}	n|d	kr|dd}
t	|
t
r@|
d
 }
d|
krPd}nJd|
kr`d}n:|d|
dkrtdnd}|d
kr|d }nt|}	d}|d
kr|ttt|d | tt|d  }	t|}|dd nt|}	|d}|dd |d d dks&|dd tkr||d
 t|}	|d}|dd |d d dkst|dd tkrtd|||	d S )!Nr   r&      Ir9   r   s   ID/Fz/Filterznot setr   ZAHxZASCIIHexDecodeZA85ZASCII85DecodeZRLZRunLengthDecodeZDCTZ	DCTDecodez/CSr1  ZRGBZCMYK   z/BPC>   /I/DeviceGray/G/Indexedr   g       @z/Wz/H   EIzHCould not extract inline image, even using fallback. Expected 'EI', got )settingsrF   )r   r   r   r   rO   r   r   r   r   rQ   re   r3   r2   r6   r4   r5   r   r   r   r   r%   )rD   rs   rO  r   r   r   r   ZfiltrZsavposrF   csZlcsbitseirG   rG   rH   rA  %  sv    










"
$
$z ContentStream._read_inline_imagerT   c                 C   s   | j st }| jD ]\}}|dkrz|d t }|d | || dd  |d ||d  |d n(|D ]}|| |d	 q~|| |d
 q| | _ | j S )Nr?  r>  rO  r   s   ID rF   rN  rx   r   )r  r   r:  ry   rz   getvalue)rD   Znew_datarB  rD  Z	dict_textoprG   rG   rH   r  q  s$    




zContentStream.get_datar  c                    s   t  | g | _d S rV   )r  r  r:  r  r  rG   rH   r    s    zContentStream.set_datac                 C   s(   | j s"| jr"| t| j d| _| j S r  )r:  r  rF  r   r`   rG   rG   rH   
operations  s    zContentStream.operations)rV  r?   c                 C   s   || _ d| _d S r  )r:  r  )rD   rV  rG   rG   rH   rV    s    c                 C   sD   | j r*| j dg df | j g df n| jr@d| j d | _d S )Nr      q   Qs   q
s   
Q
)r:  insertrC   r  r`   rG   rG   rH   isolate_graphics_state  s
    z$ContentStream.isolate_graphics_staterr   c                    s&   | j s| jr|   t || d S rV   )r  r:  r  r  rz   r   r  rG   rH   rz     s    zContentStream.write_to_stream)N)FrG   )N)!r   r   r   __doc__r   r   rg   r   r   r   r   r   r@   r   r	   r
   rM   r   r   r   r   r   rF  rA  rh   r  r  r   rV  setterrZ  rz   r6  rG   rG   r  rH   r9  n  sR    )!  &L	  r9  r{   c                 C   s  |  d}| dd |dkr*t| |S |dkrh|  d}| dd |dkr^t| ||S t| |S |dkr~t| ||S |d	krt| S |d
krt| |S |dkr|  ddkrt	 S |dkrt	| S |dkrt
|  t| }| dd t| ||S |dkr`|  d}| t| d t|d k	rV|d k	sJtdt| |S t| S |  }| dd |  d}| | t|  td|d| d|d S )Nr&   r      /   <r   rS  r   rw   )   t   f   (   e   s   endobj   nr~   s   0123456789+-.   r   iP   z(Invalid Elementary Object starting with z @z: )r   r   r+   r   r   r7   r<   r'   r8   r,   r   r   r   r   IndirectPatternmatchr   r*   r-   r   r   r$   )rs   rO   r|   r   rC  r   Zstream_extractrG   rG   rH   r     sP    











r   c                   @   s   e Zd ZdZeddddZeee dddZ	eee dd	d
Z
eed dddZeee dddZeee dddZeee dddZeee dddZeee dddZeee dddZeee dddZdS )Fieldz
    A class representing a field dictionary.

    This class is accessed through
    :meth:`get_fields()<pypdf.PdfReader.get_fields>`
    Nr  c              	   C   s   t |  t t  }|j| _|D ].}z|| | t|< W q& tk
rR   Y q&X q&t| 	dt
rtt
| td  }t|tr| }n|d krd}ntdt|| td< d S )Nr   r1  zShould never happen)r   r   r   
attributesr   rN   r+   r   rQ   r   r"  r   r  rh   decoderP   r/   )rD   rF   Zfield_attributesattrdZd_strrG   rG   rH   r     s&    


zField.__init__rT   c                 C   s   |  tjS )z4Read-only property accessing the type of this field.)r   r   r(  r`   rG   rG   rH   
field_type  s    zField.field_typec                 C   s   |  tjS )z6Read-only property accessing the parent of this field.)r   r   ZParentr`   rG   rG   rH   r     s    zField.parentr<   c                 C   s   |  tjS )z4Read-only property accessing the kids of this field.)r   r   ZKidsr`   rG   rG   rH   kids  s    z
Field.kidsc                 C   s   |  tjS )z4Read-only property accessing the name of this field.)r   r   Tr`   rG   rG   rH   name  s    z
Field.namec                 C   s   |  tjS )z>Read-only property accessing the alternate name of this field.)r   r   ZTUr`   rG   rG   rH   alternate_name  s    zField.alternate_namec                 C   s   |  tjS )z
        Read-only property accessing the mapping name of this field.

        This name is used by pypdf as a key in the dictionary returned by
        :meth:`get_fields()<pypdf.PdfReader.get_fields>`
        )r   r   ZTMr`   rG   rG   rH   mapping_name  s    zField.mapping_namec                 C   s   |  tjS )z
        Read-only property accessing the field flags, specifying various
        characteristics of the field (see Table 8.70 of the PDF 1.7 reference).
        )r   r   ZFfr`   rG   rG   rH   flags  s    zField.flagsc                 C   s   |  tjS )zs
        Read-only property accessing the value of this field.

        Format varies based on field type.
        )r   r   Vr`   rG   rG   rH   r   #  s    zField.valuec                 C   s   |  tjS )z=Read-only property accessing the default value of this field.)r   r   ZDVr`   rG   rG   rH   default_value,  s    zField.default_valuec                 C   s   |  tjS )z
        Read-only property accessing the additional actions dictionary.

        This dictionary defines the field's behavior in response to trigger
        events. See Section 8.5.2 of the PDF 1.7 reference.
        )r   r   ZAAr`   rG   rG   rH   additional_actions1  s    zField.additional_actions)r   r   r   r[  r   r   r   r	   r+   rn  r   ro  rg   rq  rr  rs  r   rt  r   r   rv  rw  rG   rG   rG   rH   ri    s,   	ri  c                   @   sd  e Zd ZU dZdZee ed< ee	e
eeef eddddZeddd	d
Zd$ee	deef ddddZeee dddZeee dddZeee dddZeee dddZeee dddZeee dddZeee dddZeee dddZeed dddZeee dd d!Z eee dd"d#Z!dS )%Destinationa  
    A class representing a destination within a PDF file.

    See section 12.3.2 of the PDF 2.0 reference.

    Args:
        title: Title of this destination.
        page: Reference to the page of this destination. Should
            be an instance of :class:`IndirectObject<pypdf.generic.IndirectObject>`.
        fit: How the destination is displayed.

    Raises:
        PdfReadError: If destination type is invalid.

    Nnode)titlepagefitr?   c                 C   s  g | _ |j}|j}t|  t|| td< || td< || td< |dkrt|dk rf|t	d t|dk r|t	d t|dk r|t	d |\| tt
j< | tt
j< | td	< nt|d
krԐn|tjkr|\| tt
j< | tt
j< | tt
j< | tt
j< n|tjtjfkrfz|\| tt
j< W n& tk
rb   t | tt
j< Y nX nr|tjtjfkrz|\| tt
j< W n& tk
r   t | tt
j< Y nX n"|tjtjfkrntd|d S )N/Title/Pager   z/XYZr&   g        r   r9   /Zoomr   zUnknown Destination Type: )Z_filtered_childrenZfit_typeZfit_argsr   r   r/   r+   r   rC   r-   TALEFTZTOPTFZFIT_RZBOTTOMRIGHTZFIT_HZFIT_BHrP   r,   ZFIT_VZFIT_BVZFITZFIT_Br$   )rD   rz  r{  r|  typargsrG   rG   rH   r   Q  sV    

zDestination.__init__r<   rT   c                    s(   t  d d g fdddD  S )Nr~  r   c                    s   g | ]}| kr | qS rG   rG   rY   r`   rG   rH   r     s   z*Destination.dest_array.<locals>.<listcomp>)/Left/Bottom/Right/Topr  )r<   r   r`   rG   r`   rH   
dest_array  s    
zDestination.dest_arrayrr   c                 C   s   |d k	rt dd |d td}|| |d | j}|| td}|| |d td}|| |d |d	 d S )
Nru   rv   r   z/Drx   z/Sz/GoTor   r   )r   ry   r+   rz   r  )rD   rs   rt   r   r   Zvalue_srG   rG   rH   rz     s$     







zDestination.write_to_streamc                 C   s
   |  dS )z3Read-only property accessing the destination title.r}  r   r`   rG   rG   rH   rz    s    zDestination.titlec                 C   s
   |  dS )z9Read-only property accessing the destination page number.r~  r  r`   rG   rG   rH   r{    s    zDestination.pagec                 C   s
   |  dS )z2Read-only property accessing the destination type.r   r  r`   rG   rG   rH   r    s    zDestination.typc                 C   s   |  ddS )z-Read-only property accessing the zoom factor.r  Nr  r`   rG   rG   rH   zoom  s    zDestination.zoomc                 C   s   |  ddS )z<Read-only property accessing the left horizontal coordinate.r  Nr  r`   rG   rG   rH   left  s    zDestination.leftc                 C   s   |  ddS )z=Read-only property accessing the right horizontal coordinate.r  Nr  r`   rG   rG   rH   right  s    zDestination.rightc                 C   s   |  ddS )z9Read-only property accessing the top vertical coordinate.r  Nr  r`   rG   rG   rH   top  s    zDestination.topc                 C   s   |  ddS )z<Read-only property accessing the bottom vertical coordinate.r  Nr  r`   rG   rG   rH   bottom  s    zDestination.bottomc                 C   s"   |  dttdtdtdgS )zHRead-only property accessing the color in (R, G, B) with values 0.0-1.0.z/Cr   )r   r<   r)   r`   rG   rG   rH   color  s     zDestination.colorc                 C   s   |  ddS )z_
        Read-only property accessing the font type.

        1=italic, 2=bold, 3=both
        rH  r   r  r`   rG   rG   rH   font_format  s    zDestination.font_formatc                 C   s   |  ddS )z
        Read-only property accessing the outline count.

        positive = expanded
        negative = collapsed
        absolute value = number of visible descendants at all levels
        r   Nr  r`   rG   rG   rH   outline_count  s    	zDestination.outline_count)N)"r   r   r   r[  ry  r	   r   __annotations__rg   r   r-   r*   r,   r1   r   r   r  r   rh   rz   rz  r   r{  r  r  r)   r  r  r  r  r  r   r  r  rG   rG   rG   rH   rx  <  sP   
5  rx  )N)]
__author____author_email__loggingr   sysior   mathr   typingr   r   r   r   r   r	   r
   r   r   r   r   Z
_protocolsr   r   r   _utilsr   r   r   r   r   r   r   r   r   	constantsr   r   r   r   r(  r    r   r!   r  r"   r  errorsr#   r$   r%   _baser'   r(   r)   r*   r+   r,   r-   r.   r/   r0   Z_fitr1   Z_image_inliner2   r3   r4   r5   r6   r7   r8   version_infor;   Ztyping_extensions	getLoggerr   loggerr   rg  r<   r   r   r  rR   r  r"  r9  rg   r   r   ri  rx  rG   rG   rG   rH   <module>   sb   4,0

 '   # R 4'  > 2c