
    j5jn1              	         d Z ddlmZ ddlZddlmZ ddl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mZmZmZmZ dd
lmZ ddlmZ ddlmZmZ  G d de      Z G d de      Z G d de      Z G d de      Z  G d d      Z! G d d      Z"d Z#dZ$dddddddddZ%d$dZ&d%d Z'd! Z(eejR                  f	 d&d"Z*d'd#Z+y)(z"PDF content stream interpretation.    )annotationsN)defaultdict)Mapping)hypotinfisclose)
NamedTuple)warn)MatrixNameObjectPdfInlineImageparse_content_stream)InputFileError)
Resolution)UNIT_SQUAREInkc                  :    e Zd ZU dZded<   ded<   ded<   ded	<   y
)XobjectSettingsz%Info about an XObject found in a PDF.strname/tuple[float, float, float, float, float, float]	shorthandintstack_depthr   fill_inkN__name__
__module____qualname____doc____annotations__     U/var/www/html/qr/venv/lib/python3.12/site-packages/ocrmypdf/pdfinfo/_contentstream.pyr   r      s    /
I>>Mr$   r   c                  :    e Zd ZU dZded<   ded<   ded<   ded	<   y
)InlineSettingsz*Info about an inline image found in a PDF.r   iimager   r   r   r   r   r   Nr   r#   r$   r%   r'   r'      s    4>>Mr$   r'   c                  D    e Zd ZU dZded<   ded<   ded<   ded<   d	ed
<   y)ContentsInfoz*Info about various objects found in a PDF.zlist[XobjectSettings]xobject_settingszlist[InlineSettings]inline_imagesboolfound_vector
found_textz#Mapping[str, list[XobjectSettings]]
name_indexNr   r#   r$   r%   r*   r*   '   s#    4++''33r$   r*   c                  0    e Zd ZU dZded<   ded<   ded<   y)TextboxInfoz%Info about a text box found in a PDF.z!tuple[float, float, float, float]bboxr-   
is_visible
is_corruptNr   r#   r$   r%   r2   r2   1   s    /
++r$   r2   c                      e Zd ZdZy)VectorMarkerzCSentinel indicating vector drawing operations were found on a page.Nr   r   r    r!   r#   r$   r%   r7   r7   9   s    Mr$   r7   c                      e Zd ZdZy)
TextMarkerzASentinel indicating text drawing operations were found on a page.Nr8   r#   r$   r%   r:   r:   =   s    Kr$   r:   c                j    t        t        |       }t        |t        d      }t	        d |D              S )z?Check if the shorthand represents a unit square transformation.F)strictc              3  >   K   | ]  \  }}t        ||d         yw)MbP?)rel_tolN)r   ).0abs      r%   	<genexpr>z"_is_unit_square.<locals>.<genexpr>E   s      @tq!wq!T**@s   )mapfloatzipr   all)r   valuespairwises      r%   _is_unit_squarerJ   A   s-    	"F6;u5H@x@@@r$   r>   grayrgbcmyk)/DeviceGrayz/CalGrayz/G
/DeviceRGBz/CalRGBz/RGB/DeviceCMYKz/CMYKc                V   t         }| dk(  r6t        |      dk(  r(|d   |k  rt        j                  S t        j                  S | dk(  rvt        |      dk(  rh|\  }}}t        |||      |k  rt        j                  S t        ||z
        |k  r!t        ||z
        |k  rt        j                  S t        j                  S | dk(  rYt        |      dk(  rK|\  }}}}	||k  r/||k  r*||k  r%|	|k  rt        j                  S t        j                  S t        j                  S t        j                  S )zClassify a device-color fill into mono/gray/color.

    ``space`` is one of 'gray', 'rgb', 'cmyk'. Any other value is treated
    conservatively as color, since we cannot prove it is achromatic.
    rK      r   rL      rM      )_INK_EPSILONlenr   monorK   maxabscolor)
spacecompsepsrgrB   cmyks
             r%   _ink_from_componentsrd   Y   s     C3u:? 8s?sxx88~#e*/1aq!Q<388Oq1u:QUs!288Oyy3u:?
1a8SQ#X Cx3885SXX5yy99r$   c                j    	 | D cg c]  }t        |       c}S c c}w # t        t        f$ r Y yw xY w)a  Convert color operands to floats, or None if any is non-numeric.

    Color operators in a malformed content stream may carry the wrong number
    of operands or a non-numeric operand (e.g. a Name). Returning None lets
    the caller keep the prior fill state instead of raising.
    N)rE   	TypeError
ValueError)operandsos     r%   _operand_floatsrj   q   s6    "*+Qa+++z" s         22c              #     K   | D ]:  \  }}t        |      }t        j                  d|      r|D ]  }g |f 
 5||f < yw)z8Convert runs of qQ's in the stack into single graphobjs.zQ*q+$N)r   rematch)	graphobjsrh   operatorchars       r%   _normalize_stackrq   ~   sW     ' '(x=88Hh'  !4j ! X&&'s   AAc                ~   g }t        |      }|}d}g }g }t        d       }	d}
d}t        dj                               }t        dj                               }t        dj                               }t        dj                               }dj	                  ||z  |z  |z        }t        t        t        | |                  D ]1  \  }}|\  }}|d	k(  rK|j                  |||f       t        |      d
kD  s4t        |      dkD  rt        d|       t        d       \|dk(  r	 |j                         \  }}}w|dk(  r	 t        |      |z  }|dk(  rt!        |      x}st#        d|      }d}|dk(  rt!        |      x}st#        d|      }d}|dk(  rt!        |      x}st#        d|      }d}|dk(  r$t$        j&                  }|st)        |d         }|dv rht+        d |D              rt$        j,                  }Ct.        j1                  |      }t!        |      }||t$        j,                  }yt#        ||      }|dk(  rW|d   }t3        ||j4                  t        |      |       }|j                  |       |	t)        |         j                  |       |d!k(  r:|d   }t7        ||j4                  t        |      |"      }|j                  |       "||v rd#}
*||v s0d#}4 t9        |||
||	$      S # t        $ r t        d       Y \w xY w# t        $ r}t        d      |d}~ww xY w)%aB  Interpret the PDF content stream.

    The stack represents the state of the PDF graphics stack.  We track the
    current transformation matrix (CTM) and the current fill color (so that
    image masks, which are painted with the fill color, can be classified);
    a full implementation would need to track many other items.

    The CTM is initialized to the mapping from user space to device space.
    PDF units are 1/72".  In a PDF viewer or printer this matrix is initialized
    to the transformation to device space.  For example if set to
    (1/72, 0, 0, 1/72, 0, 0) then all units would be calculated in inches.

    Images are always considered to be (0, 0) -> (1, 1).  Before drawing an
    image there should be a 'cm' that sets up an image coordinate system
    where drawing from (0, 0) -> (1, 1) will draw on the desired area of the
    page.

    PDF units suit our needs so we initialize ctm to the identity matrix.

    According to the PDF specification, the maximum stack depth is 32. Other
    viewers tolerate some amount beyond this.  We issue a warning if the
    stack depth exceeds the spec limit and set a hard limit beyond this to
    bound our memory requirements.  If the stack underflows behavior is
    undefined in the spec, but we just pretend nothing happened and leave the
    graphics state unchanged.
    rN   c                     g S Nr#   r#   r$   r%   <lambda>z%_interpret_contents.<locals>.<lambda>   s    R r$   FzS s f F f* B B* b b*z	TJ Tj " 'zBI ID EI q Q Do cmzg rg k cs sc scn q       z5PDF graphics stack overflowed hard limit at operator z(PDF graphics stack overflowed spec limitQz5PDF graphics stack underflowed - PDF may be malformedcmzwPDF content stream is corrupt - this PDF is malformed. Use a PDF editor that is capable of visually inspecting the PDF.Nr_   rK   rgrL   rO   rc   rM   rP   csr   )scscnc              3  <   K   | ]  }t        |t                y wrt   )
isinstancer   )r@   ri   s     r%   rC   z&_interpret_contents.<locals>.<genexpr>   s     91:a&9s   Do)r   r   r   r   zINLINE IMAGE)r(   r   r   r   T)r+   r,   r.   r/   r0   )r   r   setsplitjoin	enumeraterq   r   appendrV   RuntimeErrorr
   pop
IndexErrorrg   r   rj   rd   r   rW   r   anyrZ   _DEVICE_FILL_SPACEgetr   r   r'   r*   )contentstreaminitial_shorthandinitial_fill_inkstackctmr   
fill_spacer+   r,   r0   r.   r/   
vector_opstext_showing_ops	image_ops	color_opsoperator_whitelistngraphobjrh   ro   evalsr[   
image_namesettingsr(   inlines                               r%   _interpret_contentsr      s   : E
"
#CHJ.0*,MZ(JLJ+1134J?0023(..01I&,,./I*/?"?)"Ki"WX -m=OPQ M8 &(s?LL#x455zBu:#&OPQsS  ?@_N,1IIK)Xz
 X&, _&x00t0/=*
&x00t0/t<)
_&x00t0/=*
 xxH !-
&99999*..z:&x0=DL"yyH3E4@H!!J&--J!	H ##H-s:'..x8'a[F#--J!	F   (#L))J[M^ )#! A  N LMN  $W s*   $L?L"LL"	L<+L77L<c                   	
 | \  }}}}}}t        ||      t        ||      f
dd		
fdt        d      D        \  }}t        ||      S )az  Given the transformation matrix and image size, find the image DPI.

    PDFs do not include image resolution information within image data.
    Instead, the PDF page content stream describes the location where the
    image will be rasterized, and the effective resolution is the ratio of the
    pixel size to raster target size.

    Normally a scanned PDF has the paper size set appropriately but this is
    not guaranteed. The most common case is a cropped image will change the
    page size (/CropBox) without altering the page content stream. That means
    it is not sufficient to assume that the image fills the page, even though
    that is the most common case.

    A PDF image may be scaled (always), cropped, translated, rotated in place
    to an arbitrary angle (rarely) and skewed. Only equal area mappings can
    be expressed, that is, it is not necessary to consider distortions where
    the effective DPI varies with position.

    To determine the image scale, transform an offset axis vector v0 (0, 0),
    width-axis vector v0 (1, 0), height-axis vector vh (0, 1) with the matrix,
    which gives the dimensions of the image in PDF units. From there we can
    compare to actual image dimensions. PDF uses
    row vector * matrix_transposed unlike the traditional
    matrix * column vector.

    The offset, width and height vectors can be combined in a matrix and
    multiplied by the transform matrix. Then we want to calculated
        magnitude(width_vector - offset_vector)
    and
        magnitude(height_vector - offset_vector)

    When the above is worked out algebraically, the effect of translation
    cancels out, and the vector magnitudes become functions of the nonzero
    transformation matrix indices. The results of the derivation are used
    in this code.

    pdfimages -list does calculate the DPI in some way that is not completely
    naive, but it does not get the DPI of rotated images right, so cannot be
    used anymore to validate this. Photoshop works, or using Acrobat to
    rotate the image back to normal.

    It does not matter if the image is partially cropped, or even out of the
    /MediaBox.

    c                0    | dk7  r|| z  nt         }||z  }|S )Nr   )r   )drawnpixelsinches_per_ptscaledpis        r%   calcz_get_dpi.<locals>.calc@  s"    "'1*#m#
r$   c              3  <   K   | ]  } |   |           y wrt   r#   )r@   r   r   image_drawn
image_sizes     r%   rC   z_get_dpi.<locals>.<genexpr>F  s      JADQA7Js      )g      R@)r   ranger   )ctm_shorthandr   rA   rB   r`   d_dpi_wdpi_hr   r   s    `       @@r%   _get_dpir     sW    \ %Aq!Q1 1+uQ{*K KqJLE5eU##r$   )r[   r   r\   zlist[float]returnr   )r   zlist[float] | None)r   r   )r   r   ),r!   
__future__r   rl   collectionsr   collections.abcr   mathr   r   r   typingr	   warningsr
   pikepdfr   r   r   r   r   ocrmypdf.exceptionsr   ocrmypdf.helpersr   ocrmypdf.pdfinfo._typesr   r   r   r'   r*   r2   r7   r:   rJ   rU   r   rd   rj   rq   rW   r   r   r#   r$   r%   <module>r      s    ) " 	 # # $ $   N N . ' 4j Z 4: 4* N NL LA  
	 0
' .9388AAH:$r$   