o
    Zh0h                     @   s  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 ddl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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m Z  ddl!m"Z"m#Z# de_$G dd de%Z&G dd dZ'G dd dej(Z)G dd dej(Z*G dd dZ+		d/dd Z,d!d" Z-d#d$ Z.d%d& Z/d'd( Z0G d)d* d*Z1G d+d, d,e1Z2G d-d. d.e1Z3dS )0z+Fetch and decode images in various formats.    N)md5)BytesIO)cycle)inf)Path)urlparse)url2pathname)ElementTree)Image	ImageFileImageOps)parse_color   )DEFAULT_OPTIONS
percentage)LOGGER)SVG)URLFetchingErrorfetchTc                   @   s   e Zd ZdZedd ZdS )ImageLoadingErrorzpAn error occured when loading an image.

    The image data is probably corrupted or in an invalid format.

    c                 C   s.   t |j}t|}| |r| d| S |S )Nz: )type__name__str)cls	exceptionnamevalue r   G/var/www/html/rh/venv/lib/python3.10/site-packages/weasyprint/images.pyfrom_exception$   s   
z ImageLoadingError.from_exceptionN)r   
__module____qualname____doc__classmethodr    r   r   r   r   r      s    r   c                   @   sL   e Zd ZdddefddZdd Zdd Zdd
dZdd Ze	dd Z
dS )RasterImageNnonec                 C   s  |}t ||}||ur|j|_d  }}|| _|d u ri n|| _|d  | _}	|d | _d|jv r6|d}n
|jdv r@|d}|j| _|j	| _	|j
| _
| j
dkrW| j	| j
 nt| _|d  | _}
t|d	i d
}| jdkor|d u| _|jdv rd| _|d u s|
s|	d urt }d|
d}| jd ur| j|d< |j|fi | | }d }n d| _|d u s|
s|jdkrt }|j|d|
d | }d }| ||| _d S )Njpeg_qualitydpitransparencyRGBA)1PIRGBr   optimize_imagesappAPP14CMYK)JPEGMPOr3   formatoptimizequalityPNG)rotate_pillow_imager6   id_cache_jpeg_quality_dpiinfoconvertmodewidthheightr   ratior7   getattrgetinvert_colorsior   savegetvaluecache_image_data
image_data)selfpillow_imageimage_idrL   filenamecacheorientationoptionsoriginal_pillow_imager'   r7   app14
image_filer   r   r   __init__,   sL   








zRasterImage.__init__c                 C   s   | j | | j| | jfS N)rB   rC   rD   )rM   
resolution	font_sizer   r   r   get_intrinsic_size`   s   zRasterImage.get_intrinsic_sizec                 C   s   | j dks
| jdkrd S |dk}d}| jrFd}t||jd d  | }t||jd d  | }	t| j | | j|	 }
|
| jkrF| j|
 }|| ||}||dd| d| || d S )Nr   autor   gqq?)	rB   rC   r>   absctmmax	add_image	transformdraw_x_object)rM   streamconcrete_widthconcrete_heightimage_renderinginterpolaterD   pt_to_inwidth_inchesheight_inchesr(   
image_namer   r   r   drawc   s    

zRasterImage.drawsourcec                 C   s6   |rt |S | j d| d| jpd }t| j||S )N- )LazyLocalImager;   r>   	LazyImager<   )rM   datarP   slotkeyr   r   r   rK   v   s   zRasterImage.cache_image_datac                 C   s8  |dkr| j | j}}nBtt| jj}tdt	| j | }tdt	| j| }|
||f t }|j||j| jd |j |j}}| | | _| jdv rVd}n| jdv r^d}n| jdkrfd}n	td	| j d}td
d|||d|r{dndd}| jdkr| jrtd|d< d|d< t| jg|S d|d< td|d|d< | jdv rd|d d< | jdv rtt| jj}	|	d}
|	| jd d }	| |	}| |
}| j|dd}tj|gdd
dtd|d||dd|rdndd 	d!|d"< n| tt| jj}t| j|d#dg|S )$Nr   r5   )r.   r*   z
/DeviceRGB)LLAz/DeviceGrayr2   z/DeviceCMYKzUnknown image mode: %sz/XObjectz/Image   truefalse)TypeSubtypeWidthHeight
ColorSpaceBitsPerComponentInterpolater3   )r   r   r   r   r   r   r   r   Decodez
/DCTDecodeFilterz/FlateDecode   )	PredictorColumnsDecodeParms   Colors)r*   rv   Astreamalpha)rs   )	r   rz   r{   r   r|   r}   r~   r   r   )extraSMaskrc   )rB   rC   r
   openrH   r   rL   rr   r_   round	thumbnailrI   r6   r7   rK   rJ   rA   r   warningpydyf
DictionaryrG   ArrayStream
getchannelr@   _get_png_data)rM   rg   	dpi_ratiorB   rC   r   rV   color_spacer   rN   alphapng_data
alpha_datarc   r   r   r   get_x_object}   s   












zRasterImage.get_x_objectc                 C   s   t  }| j|dd |d g }|d}|rFtd|\}|d}|dkr1||| n||tj |dtj |d}|sd	|S )Nr9   )r6   rw      z!Is   IDAT    )
r   rI   seekreadstructunpackappendrH   SEEK_CURjoin)rN   rV   r   raw_chunk_lengthchunk_length
chunk_typer   r   r   r      s   




zRasterImage._get_png_data)Nrm   )r   r!   r"   r   rW   r[   rl   rK   r   staticmethodr   r   r   r   r   r%   +   s    
4
Sr%   c                       (   e Zd Z fddZedd Z  ZS )rq   c                    s"   t    || _|| _|||< d S rX   )superrW   _keyr<   )rM   rQ   rt   rr   	__class__r   r   rW      s   
zLazyImage.__init__c                 C   s   | j | j S rX   )r<   r   rM   r   r   r   rr      s   zLazyImage.datar   r!   r"   rW   propertyrr   __classcell__r   r   r   r   rq      s    rq   c                       r   )rp   c                    s   t    || _d S rX   )r   rW   	_filename)rM   rP   r   r   r   rW      s   

zLazyLocalImage.__init__c                 C   s   t | j S rX   )r   r   
read_bytesr   r   r   r   rr      s   zLazyLocalImage.datar   r   r   r   r   rp      s    rp   c                   @   s$   e Zd Zdd Zdd Zdd ZdS )SVGImagec                 C   s"   t ||| _|| _|| _|| _d S rX   )r   _svg	_base_url_url_fetcher_context)rM   treebase_urlurl_fetchercontextr   r   r   rW     s   
zSVGImage.__init__c                 C   s   | j |\}}d ||fv r6| j  }|r3|d r3|d r3|d |d  }|r,|| }n|r2|| }nd }n|r?|r?|| }nd}|||fS )N   r   r   )r   r[   get_viewbox)rM   image_resolutionrZ   rB   rC   viewboxrD   r   r   r   r[   
  s   



zSVGImage.get_intrinsic_sizec              
   C   sf   z| j |||| j| j| j W d S  ty2 } ztd| j tjd|d W Y d }~d S d }~ww )NzFailed to render SVG image %sz Error while rendering SVG image:exc_info)	r   rl   r   r   r   BaseExceptionr   errordebug)rM   rc   rd   re   rf   r   r   r   r   rl     s   

zSVGImage.drawN)r   r!   r"   rW   r[   rl   r   r   r   r   r     s    r   
from-imagec                 C   s  || v r| | S zt ||1}t|d}|jdkr!t|j}	nd}	d|v r,|d }
n|d  }
|p7|d }W d   n1 sBw   Y  d}g }|dkruzt|
}t	||||}W n t
yt } z|| W Y d}~nd}~ww |du rz	tt|
}W n8 t
y } z,|dkrt|d zt|
}t	||||}W n t
y   t|w W Y d}~nd}~ww t| d	d
 }t|||
|	| ||}W n$ ttfy } ztd|| tjd|d d}W Y d}~nd}~ww || |< |S )z(Get an Image instance from an image URI.redirected_urlfileNstringfile_obj	mime_typezimage/svg+xmlr   F)usedforsecurityzFailed to load image at %r: %szError while loading image:r   )r   r   rF   schemer   pathr   r	   
fromstringr   	Exceptionr   r
   r   r   r   r    r   encode	hexdigestr%   r   r   r   r   )rQ   r   rS   urlforced_mime_typer   rR   result
parsed_urlrP   r   r   imagesvg_exceptionsr   svg_exceptionrN   raster_exceptionrO   r   r   r   r   get_image_from_uri&  sh   





r   c                 C   st   | j }|dkrd| jv rt| } n#|dkr5|\}}|dkr,ttjd| }| |} |r5| tjj} || _ | S )z{Return a copy of a Pillow image with modified orientation.

    If orientation is not changed, return the same image.

    r   exifr&   r   ROTATE_)	r6   r?   r   exif_transposerE   r
   	Transpose	transposeFLIP_LEFT_RIGHT)rN   rR   image_formatanglefliprotationr   r   r   r:   a  s    


r:   c           	         s    fdd|D }|d du rd|d< |d du r |d< |d }t |D ]\}}|dur8||k r6|||< q%|}q%d}t |D ](\}}|durg|| }|| ||  }t|d |D ]
}|||  ||< qZ|}q?|S )a  Give color stops positions on the gradient vector.

    ``vector_length`` is the distance between the starting point and ending
    point of the vector gradient.

    ``positions`` is a list of ``None``, or ``Dimension`` in px or %. 0 is the
    starting point, 1 the ending point.

    See https://drafts.csswg.org/css-images-3/#color-stop-syntax.

    Return processed color stops, as a list of floats in px.

    c                    s   g | ]}t | qS r   r   .0positionvector_lengthr   r   
<listcomp>  s    z'process_color_stops.<locals>.<listcomp>r   Nr   r   )	enumeraterange)	r   	positionsprevious_posir   
previous_ibase	incrementjr   r   r   process_color_stopsy  s,   
r   c                    sP   | d | d  }|  dkrdgt |  } n
 fdd| D }  || fS )zNormalize stop positions between 0 and 1.

    Return ``(first, last, positions)``.

    first: original position of the first position.
    last: original position of the last position.
    positions: list of positions between 0 and 1.

    r   r   c                    s   g | ]}|   qS r   r   )r   posfirsttotal_lengthr   r   r         z,normalize_stop_positions.<locals>.<listcomp>)len)r   lastr   r   r   normalize_stop_positions  s   

r   c              
   C   sl  t |}|dks
J |t | ksJ |d |d  }|dkr(tt|}|d }dd | D }dd | D }dd | D }dd | D }d } }	 }
}d	| }t|dd
 dD ]7\}}|||d   | }|d |fD ]"}||| | 7 }|	|| | 7 }	|
|| | 7 }
||| | 7 }qmqY|dkrtdS td|| d  d|	| d  d|
| d  d| d	S )zG
    https://drafts.csswg.org/css-images-3/#gradient-average-color
    r   r   r   c                 S   s   g | ]
\}}}}|| qS r   r   r   rgbar   r   r   r         z*gradient_average_color.<locals>.<listcomp>c                 S   s   g | ]
\}}}}|| qS r   r   r   r   r   r   r     r  c                 S   s   g | ]
\}}}}|| qS r   r   r   r   r   r   r     r  c                 S   s   g | ]\}}}}|qS r   r   r   r   r   r   r     r   r   Ntransparentzrgb(    /))r   listr   r   r   )colorsr   nb_stopsr   premul_rpremul_gpremul_br   result_rresult_gresult_bresult_atotal_weightr   r   weightr   r   r   r   gradient_average_color  s<   
r  c                   @   s,   e Zd Zdd Zdd Zdd Zdd Zd	S )
Gradientc                 C   s:   |sJ t dd |D | _t dd |D | _|| _d S )Nc                 s   s    | ]\}}|V  qd S rX   r   )r   color_r   r   r   	<genexpr>      z$Gradient.__init__.<locals>.<genexpr>c                 s   s    | ]\}}|V  qd S rX   r   )r   r  r   r   r   r   r    r  )tupler  stop_positions	repeating)rM   color_stopsr  r   r   r   rW     s   
zGradient.__init__c                 C   s   dS )N)NNNr   )rM   r   rZ   r   r   r   r[     s   zGradient.get_intrinsic_sizec                    sP  |  ||\}}}}|dkr$dd|| d    d S dd D   fddtt d D }	fddttd D }
t D ],\}}|dkry|dkrg|
|d  d |
|d  d< |td k ry|
| d |
| d< qMt|	D ]\}\}}d||fvr||fdkr|| |
| d	< q~|d
krd	nd}|d |d f}| j }td d }|dd }fdd|
D }||||}	|d||||}j
|d tdd  D r dd||}|d
krd	nd}fdd|	D }||||}|	|d||||}|j
|d d|j dg|_|j d S )Nsolidr   c                 S   s   g | ]}|d  qS )r   r   )r   r  r   r   r   r         z!Gradient.draw.<locals>.<listcomp>c                    s    g | ]} |  |d   fqS r   r   r   r   )alphasr   r   r         r   c                    s>   g | ]} |  d dd  |d   d dd dgqS )srgbNr   r   )tor$  )r  r   r   r     s    0)r   r   r   linearr   r   r   r   c                 3   s&    | ]\}}}  d |||V  qdS )r*  Ncreate_interpolation_function)r   c0c1nrc   r   r   r    s
    
z Gradient.draw.<locals>.<genexpr>r.   )dc                 s   s    | ]}|d kV  qdS )r   Nr   )r   r   r   r   r   r    r  c                 3   s(    | ]\}}  d |f|fdV  qdS )r*  r   Nr+  )r   r-  r.  r0  r   r   r    s
    
Grayr	  z sh)layout	rectangle	set_colorfillr   r   r   r  create_stitching_functionadd_shadingra   anyset_alpha_stater;   rc   paint_shading)rM   rc   rd   re   _image_renderingscale_ytype_pointsr   alpha_couplescolor_couplesr   r   a0a1shading_typedomainextendr   boundssub_functionsfunctionshadingalpha_streamalpha_shadingr   )r%  r  rc   r   rl     st   



zGradient.drawc                 C   s   t )a]  Get layout information about the gradient.

        width, height: Gradient box. Top-left is at coordinates (0, 0).

        Returns (scale_y, type_, points, positions, colors).

        scale_y: vertical scale of the gradient. float, used for ellipses
                 radial gradients. 1 otherwise.
        type_: gradient type.
        points: coordinates of useful points, depending on type_:
            'solid': None.
            'linear': (x0, y0, x1, y1)
                      coordinates of the starting and ending points.
            'radial': (cx0, cy0, radius0, cx1, cy1, radius1)
                      coordinates of the starting end ending circles
        positions: positions of the color stops. list of floats in between 0
                   and 1 (0 at the starting point, 1 at the ending point).
        colors: list of (r, g, b, a).

        )NotImplementedError)rM   rB   rC   r   r   r   r3  &  s   zGradient.layoutN)r   r!   r"   rW   r[   rl   r3  r   r   r   r   r    s
    	>r  c                   @   s   e Zd Zdd Zdd ZdS )LinearGradientc                 C   s   t | || |\| _| _d S rX   )r  rW   direction_type	direction)rM   r   rP  r  r   r   r   rW   ?  s   zLinearGradient.__init__c                    s  t | jdkrddd g | jd gfS | jdkrB| jd\}}|dkr%dnd}|dkr-dnd}t||}|| | }|| | }	n| jd	ksIJ | j}
t|
}t|
 }	t	|d
t	|	d
}}	t
| j}t|| t||	  }t|| j | js d  d kr d d d  |d|d   d  d kr  d d  ||d  t \}} | jrO||krt| }ddd g |gfS || }|dksJ  fddtt  d D }tdg|R }t|}tdg|d d d R }t|d d d }||k r)t|}|t|   d |  ||| 7 }||k s
|dkrOt|}|dt|  d d |  ||| 8 }|dks.|||  d }||	|  d }|||  ||	|  |||  ||	|  f}dd| |fS )Nr   r!  r   cornerr  leftr   topr   	   c                    s    g | ]} |d    |  qS r#  r   r$  r   r   r   r   w  r&  z)LinearGradient.layout.<locals>.<listcomp>r   r)  )r   r  rO  rP  splitmathhypotsincosr   r  r]   r   r  r  insertr   r   r  r   r   next)rM   rB   rC   yxfactor_xfactor_ydiagonaldxdyr   r  r   r   r   r  stop_lengthposition_steps
next_stepsnext_colorsprevious_stepsprevious_colorsstepstart_xstart_yr?  r   rV  r   r3  D  sp   








zLinearGradient.layoutN)r   r!   r"   rW   r3  r   r   r   r   rN  >  s    rN  c                   @   s4   e Zd Zdd Zdd Zdd Zdd Zd	d
 ZdS )RadialGradientc                 C   s*   t | || || _|| _|\| _| _d S rX   )r  rW   centershape	size_typesize)rM   r   rp  rr  ro  r  r   r   r   rW     s   zRadialGradient.__init__c                    s  t | jdkrddd g | jd gfS | j\}}}}t||}t||}|dkr+|| }|dkr3|| }| j| |||| \}}|| }	t| j}
t|| j}| j	s|d dkrn|d |d krn|
dd |

d|
d  |d |d kr||d d  |
|
d  |d dk r| j	r|d |d  }|d|d  |     fdd	|D }ni|d dkrddd g | jd gfS t|D ]S\}}|dkr|
|d  ||d  }
} n=|dkr|
| }|
|d  }||d  }|dk sJ t||||g|dd|g}|g|
|d   }
dg||d   } nqt|\}}}||kr3| j	r3t|
|}ddd g |gfS |||	 ||||	 |f}| j	rP| |||	|||
\}}}
|	d
|||
fS )Nr   r!  r   rightbottomrU  r   c                    s   g | ]}|  qS r   r   r   offsetr   r   r     r"  z)RadialGradient.layout.<locals>.<listcomp>radial)r   r  ro  r   _handle_degenerate_resolve_sizer  r   r  r  r\  r   r   r  r   _repeat)rM   rB   rC   origin_xcenter_xorigin_ycenter_ysize_xsize_yr=  r  r   r   r   r   r  previous_colorprevious_positionintermediate_colorr   r   r?  r   ru  r   r3    st   









zRadialGradient.layoutc              	      s  |  }  |d |d  }tt||d  || |d  t||d  |d  | t|d  || |d  t|d  |d  | }	t|	|d  | }
|
dkr|d|
 }||9 }fddt|D |d d |d ||
  f }|d dkr||fS |d | }|d d d |dd   }t|  r||  7 } fd	dt D  |  }|dkr||fS d d
 fdksJ d|  k rdk sJ  J d d d
 }d| }t|ddD ]\}}||kr|| d  | } fdd| d  D }| ||f  S ||k rr||  }||d   }|d   }||||g}||||g}t||}|g||d  d   | } fdd|d  d  D }|d   g|R ||f  S qd S )N   r   r   r   c                    s   g | ]} D ]}|| qqS r   r   r   r   r   rV  r   r   r     s
    z*RadialGradient._repeat.<locals>.<listcomp>)r   r   c                    s"   g | ]}D ]}|  | qqS r   r   r  )full_repeatoriginal_positionsr   r   r     s    
r   r*  )startc                    s   g | ]}|  d  qS r#  r   r   r  r   r   r   1  s    
c                    s   g | ]}|d    qS r#  r   r   r  r   r   r   B  s    )	copyr_   rX  rY  ceilr   intr   r  )rM   rB   rC   r=  r?  r   r  original_colorsgradient_lengthmax_distancerepeat_afterrepeatrepeat_beforepartial_repeatreverserD   r   r   new_positionsr  
next_colornext_positionaverage_colorsaverage_positions
zero_colorr   )r  r  r   r   rz    sz   







zRadialGradient._repeatc                 C   s2  | j dkr| j\}}t||}t||}||fS t|}t|| }t|}	t|| }
| jdr4tnt}| jdrV| jdkrL||||	|
}||fS |||||	|
fS | jdkrv|t	
||	t	
||
t	
||	t	
||
}||fS |||	f||
f||	f||
fdd d\}}|t	d |t	d fS )	z+Resolve circle size of the radial gradient.explicitclosestsidecirclec                 S   s
   t j|  S rX   )rX  rY  )r  r   r   r   <lambda>b  s   
 z.RadialGradient._resolve_size.<locals>.<lambda>)rt   r   )rq  rr  r   r]   
startswithminr_   endswithrp  rX  rY  sqrt)rM   rB   rC   r|  r~  r  r  rR  rs  rS  rt  picksize_xycorner_xcorner_yr   r   r   ry  H  s2   






zRadialGradient._resolve_sizec                 C   sX   ||  kr
dkrn nd }}||fS |dkr d}d}||fS |dkr(d}d}||fS )ztHandle degenerate radial gradients.

        See https://drafts.csswg.org/css-images-3/#degenerate-radials

        r   gHz>g    cAr   )rM   r  r  r   r   r   rx  e  s   z!RadialGradient._handle_degenerateN)r   r!   r"   rW   r3  rz  ry  rx  r   r   r   r   rn    s    ORrn  )NNr   )4r#   rH   rX  r   hashlibr   r   	itertoolsr   r   pathlibr   urllib.parser   urllib.requestr   	xml.etreer	   r   PILr
   r   r   tinycss2.color4r   ro   r   layout.percentr   loggerr   svgr   urlsr   r   LOAD_TRUNCATED_IMAGES
ValueErrorr   r%   Objectrq   rp   r   r   r:   r   r   r  r  rN  rn  r   r   r   r   <module>   sJ     C
#
;-"c[