
    q3j"                     F   S SK r S SKrS SKrS SKJs  Jr  S SKJ	r	  S SK
JrJrJrJrJr   S SK
Jr  S\R&                  S\4S jrS SKJr  S	S
KJr  SrSrS\R&                  S\\R&                  \\\4   4   4S jr  S#S\R&                  S\S\S\S\\   4
S jjrS\R&                  S\S\S\R&                  4S jr \4S\R&                  S\S\S\R&                  4S jjr! S$S\R&                  S\R&                  S\R&                  S\S\R&                  4
S jjr"   S%S\R&                  S\R&                  S\R&                  S\S\RF                  S-  S\RF                  S-  S\R&                  4S jjr$\" SS S!9 " S" S\	RJ                  5      5       r&g! \ a    Sr GNnf = f)&    N)io)PyrUpbuild_laplacian_pyramidbuild_pyramidfind_next_powerof_twois_powerof_two)padimageborder_typec                     [         b  [        XU5      $ UnUS:X  a  [        R                  " XSS9$ [        R                  " XUS9$ )Nreflectmode)_kornia_padFr	   )r
   paddingr   r   s       N/home/wildlama/comfy/ComfyUI/custom_nodes/ComfyUI-LTXVideo/pyramid_blending.py_padr      sD    5;77DyuuU)4455d++    )Tensor   )
comfy_node   @   returnc                     U R                   S   U R                   S   p!SnSn[        U5      (       a  [        U5      (       d-  [        U5      U-
  n[        U5      U-
  n[        U SUSU4S5      n XU44$ )zFPad an image tensor so H and W are powers of two (kornia requirement).      r   r   )shaper   r   r   )r
   hw	pad_rightpad_downs        r   _pad_for_laplacianr$   $   s{    ;;q>5;;q>qIH1."3"3)!,q0	(+a/UQ	1h7Ch'''r   images	max_levelalign_cornersc                     U R                   S   U R                   S   pT[        U5      (       a  [        U5      (       d*  S[        U5      U-
  S[        U5      U-
  4n[        XU5      n [	        XX#5      $ )Nr   r   r   )r   r   r   r   r   )r%   r&   r   r'   r    r!   r   s          r   _gaussian_pyramidr)   0   sn     <<?FLLOq1."3"3+A.2A7LQ7ORS7STf{3KGGr   	long_sider   c           	      :   U R                   SS  u  p4[        X45      nXQ:X  a  U $ X-  n[        S[        [        X6-  5      5      5      n[        S[        [        XF-  5      5      5      nUS:X  a  [        R
                  " XU4US9$ [        R
                  " U Xx4USS9$ )Nr   nearest)sizer   Fr.   r   r'   )r   maxintroundr   interpolate)	r%   r*   r   r    r!   current_long_sidescale	resized_h	resized_ws	            r   _resize_preserving_aspect_ratior8   =   s     <<DAA	%)EAs5+,-IAs5+,-Iy}}Vi*@tLL==#	 r   maskspatial_radiusc                     US::  a  U $ U R                   SS  n[        U R                  5       USS9n[        R                  " UUS-  S-   SUS9n[        R
                  " UUSSS	9$ )
Nr   r,   bilinearr   r   r   )kernel_sizestrider   Fr/   )r   r8   floatr   
max_pool2dr3   )r9   r:   r*   original_sizemask_low_ress        r   _apply_low_res_mask_dilationrC   T   s|    
 JJrsOM2

ijL <<"Q&*	L ==	 r   image1image2c                    [        XS9n[        XS9n[        X#S9n[        5       nUS   US   -  US   SUS   -
  -  -   n[        [	        U5      S-
  SS5       H$  n	XI   Xi   -  XY   SXi   -
  -  -   n
U" U5      U
-   nM&     U$ )z9Blend a single chunk (already padded, already on device).r&   r   r   )r   r)   r   rangelen)rD   rE   r9   r&   pyramid1pyramid2pyramid_maskpyr_upoutputiresiduals              r   _pyramid_blend_chunkrR   n   s     'vCH&vCH$T?LWFb\L,,x|q<PRCS?S/TTF3x=1$b"-;08;!loBU3VV(* . Mr   deviceoutput_devicec                 x   U R                   UR                   :w  a%  [        SU R                    SUR                    35      eU R                   S   UR                   S   :w  a  [        S5      eU R                   SS  UR                   SS  :w  a  [        S5      e[        U S S 5      u  pgU R                   S   U R                   S   p[        XS   -   XS   -   5      n
[        U[	        [
        R                  " U
5      5      5      n[        U5      (       a3  [        R                  R                  R                  USUS   SUS   4S	S
9nU R                   S   n/ n[        SU[        5       H  n[        U[        -   U5      n[        XU 5      u  p[        XU 5      u  nnX-U nUb3  UR                  U5      nUR                  U5      nUR                  U5      n[        UUUUS9nUSS U2S U	24   R!                  SS5      nUR#                  Ub  UR                  U5      OU5        M     [        R$                  " USS9$ )Nz&input images must have the same size, z != r   zFimage_a, image_b, and mask must have the same frame count for blendingr,   zMimage_a, image_b, and mask must have the same spatial resolution for blendingr   rH   r   r   rG   .)dim)r   
ValueErrorr$   minr1   mathlog2anytorchnn
functionalr	   rI   _CHUNK_SIZEtorR   clampappendcat)rD   rE   r9   r&   rS   rT   _r   orig_horig_w
padded_minBresultsstartend
img1_chunk
img2_chunk
mask_chunk	out_chunkcroppeds                       r   _pyramid_blendrq      s5    ||v||#4V\\N$v||nU
 	
 ||A$**Q-'T
 	
 ||BCDJJrsO+[
 	
 $F2AJ/JA\\"%v||B'7FVaj(&1:*=>JIs499Z#89:I
7||xx""&&1gaj!WQZ0y ' 
 	QAGq![)%+%q)*6+<=
*6+<=
A_
#v.J#v.J#v.J(
J)
	 C&'6'1288A>)6)BGJJ}%	
! *( 99W!$$r   LTXVLaplacianPyramidBlendzLTX Laplacian Pyramid Blend)namedescriptionc                       \ rS rSrSr\S 5       r\S\R                  S\R                  S\R                  S\	S\
S	\R                  4S
 j5       rSrg)rr      zIBlend two images seamlessly using Laplacian pyramid blending with a mask.c                    [         R                  " SSS[         R                  R                  SSS9[         R                  R                  SSS9[         R                  R                  S	S
S9[         R
                  R                  SSSS9[         R                  R                  SSSSSS9/[         R                  R                  S5      /S9$ )Nrr   zLightricks/utilityz=Blend two images seamlessly using Laplacian pyramid blending.image_azFirst source image.)tooltipimage_bzSecond source image.r9   z.Blend mask (white = image_a, black = image_b).trim_to_shortestTzPTrim image_a, image_b, and mask to the shortest sequence length before blending.)defaultry   mask_low_res_dilation   r      z]Downscale the mask to long side 64, dilate it spatially, then resize it back before blending.)r|   rX   r0   ry   r
   )node_idcategoryrt   inputsoutputs)r   SchemaImageInputMaskBooleanIntOutput)clss    r   define_schema'LTXVLaplacianPyramidBlend.define_schema   s    yy/)W1   2   L   

  & n ! 
 +{  %6 (=!
 !	
r   rx   rz   r9   r{   r}   r   c           	         [         R                  R                  5       nUR                  S:X  a  US S 2S S 2S S 2S4   nUR                  S:X  a  UR	                  S5      nUR
                  SS UR
                  SS :w  a  [        S5      eUR
                  SS UR
                  SS :w  a  [        S5      eU(       aD  [        UR
                  S   UR
                  S   UR
                  S   5      nUS U nUS U nUS U nOAUR
                  S   UR
                  S   s=:X  a  UR
                  S   :X  d  O  [        S5      eUR                  SSSS5      nUR                  SSSS5      n	UR	                  S5      R                  5       n
[        X5      n
[        UU	U
S	U[         R                  R                  5       S
9n[        R                  " UR                  SSSS5      5      $ )N   r   r   r   r   z9image_a and image_b must have the same spatial resolutionz@image_a, image_b, and mask must have the same spatial resolutionz\image_a, image_b, and mask must have the same frame count unless trim_to_shortest is enabled   )r&   rS   rT   )comfymodel_managementget_torch_devicendim	unsqueezer   rW   rX   permuter?   rC   rq   intermediate_devicer   
NodeOutput)r   rx   rz   r9   r{   r}   rS   shortestoriginaltargetmask_4dresults               r   execute!LTXVLaplacianPyramidBlend.execute   s    ''88:99>1a
#D99>>>!$D==1q!33K  ==1Aa0R  7==+W]]1-=tzz!}MHix(Gix(G	?D--"gmmA&6G$**Q-Gn  ??1aA.Aq!,..#))+.wN00DDF
 }}V^^Aq!Q788r    N)__name__
__module____qualname____firstlineno____doc__classmethodr   r\   r   boolr1   r   r   r   __static_attributes__r   r   r   rr   rr      sy    
 T"
 "
H 0909 09 ll	09
 09  #09 
09 09r   )r   F)r   )r   NN)'rY   comfy.model_managementr   r\   torch.nn.functionalr]   r^   r   comfy_api.latestr   !kornia.geometry.transform.pyramidr   r   r   r   r   r	   r   ImportErrorr   strr   nodes_registryr   r_   _MASK_LOW_RES_LONG_SIDEtupler1   r$   r   listr)   r8   rC   rR   rS   rq   	ComfyNoderr   r   r   r   <module>r      s-         D
, ,C ,  & 	(ell 	(uU\\5c?5R/S 	( !	
HLL
H
H 
H 	
H
 
&\
HLL%(03
\\4 -
,,  \\	< 	LLLL ,, 	
 \\0 "&)-6%LL6%LL6% ,,6% 	6%
 LL46% <<$&6% \\6%r 	$-Y9 Y9	Y9]  Ks   F F F 