
    j5j                       d Z ddlm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ZddlmZmZmZmZmZ  ej$                  e      ZdZddd		 	 	 	 	 	 	 	 	 dd
Z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y)zAUtilities for PDF/A production and confirmation with Ghostscript.    )annotationsN)Iterator)files)Path)Array
DictionaryNamePdfStreamzsRGB.iccstream_namestream_datac             #  @  K   |d u |d u k(  sJ |rdnd}|r8|J t        j                  |d      j                  d      }| d|z    d | dk7  rd	|  d
| d d|  d |j                         D ]  \  }}d| d|   d |rd|  d|dd   d y y w)Nz/streamz/dictT)adobeascii def	{Catalog}z
[/_objdef z /type z /OBJ pdfmark[z <<z  z>> /PUT pdfmark   z /PUT pdfmark)base64	a85encodedecodeitems)alias
dictionaryr   r   objtypea85_datakeyvals           C/var/www/html/qr/venv/lib/python3.12/site-packages/ocrmypdf/pdfa.py_postscript_objdefr"      s      4[D%8999&iGG&&&##Kt<CCGLQ(**5'	??eWC.$$& S3%q
%+ab/*-88 s   BBc           	   #     K   d t        ddt        |      id|      E d {    d t        ddd	dd
|  dd      E d {    d t        dddi      E d {    y 7 @7 !7 	w)Nz%!z
{icc_PDFA}z/Nz/ICCProfiler    z{OutputIntent_PDFA}z/OutputIntent
/GTS_PDFA1())/Type/S/DestOutputProfile/OutputConditionIdentifierr   z/OutputIntentsz[ {OutputIntent_PDFA} ])r"   str)icc_nameicc_datacolorss      r!   _make_postscriptr0   3   s     
J!	s6{!	   H!$".,-hZq/		
   H!&(AB  #s3   "A+A% A+A'A+A) A+'A+)A+c                    |dk7  rt        d      t        d      t        z  j                         }dj	                  t        ||d            }t        |       j                  |d       | S )a  Create a Postscript PDFMARK file for Ghostscript PDF/A conversion.

    pdfmark is an extension to the Postscript language that describes some PDF
    features like bookmarks and annotations. It was originally specified Adobe
    Distiller, for Postscript to PDF conversion.

    Ghostscript uses pdfmark for PDF to PDF/A conversion as well. To use Ghostscript
    to create a PDF/A, we need to create a pdfmark file with the necessary metadata.

    This function takes care of the many version-specific bugs and peculiarities in
    Ghostscript's handling of pdfmark.

    The only information we put in specifies that we want the file to be a
    PDF/A, and we want to Ghostscript to convert objects to the sRGB colorspace
    if it runs into any object that it decides must be converted.

    Arguments:
        target_filename: filename to save
        icc: ICC identifier such as 'sRGB'
    References:
        Adobe PDFMARK Reference:
        https://opensource.adobe.com/dc-acrobat-sdk-docs/library/pdfmark/
    sRGBzOnly supporting sRGBocrmypdf.data
   r   )encoding)NotImplementedErrorpackage_filesSRGB_ICC_PROFILE_NAME
read_bytesjoinr0   r   
write_text)target_filenameiccbytes_icc_profile
postscripts       r!   generate_pdfa_psrA   K   sn    0 f}!"899 	o&)>>jl  +C1BAFGJ 	$$Z'$B    c                "   t        j                  |       5 }|j                         }|j                  sddddcddd       S h d}|j                  j	                         }d| }i }||v r
d|d	<   d
|d<   ||d<   ddd       |S # 1 sw Y   S xY w)zDetermines if the file claims to be PDF/A compliant.

    This only checks if the XMP metadata contains a PDF/A marker. It does not
    do full PDF/A validation.
    FpdfzNo PDF/A metadata in XMP)passoutputconformanceN>   1a1b2a2b2u3a3b3uzPDF/A-TrE   pdfarF   rG   )pikepdfopenopen_metadatapdfa_statuslower)filenamerD   pdfmetavalid_part_conformspdfa_status_isorG   	pdfa_dicts          r!   file_claims_pdfar[   q   s     
h	 /3##%""9/ / O "--335/0+-	11 $If"(Ih#.	- #/$ %/$ s   "B8BBc                 B    t        d      t        z  j                         S )z,Load the sRGB ICC profile from package data.r3   )r8   r9   r:    rB   r!   _load_srgb_icc_profiler^      s    /*-BBNNPPrB   c                4    ddddd}|j                  | d      S )zExtract PDF/A part and conformance from output_type.

    Args:
        output_type: One of 'pdfa', 'pdfa-1', 'pdfa-2', 'pdfa-3'

    Returns:
        Tuple of (part, conformance) e.g., ('2', 'B')
    )2B)1ra   )3ra   )rP   zpdfa-1zpdfa-2zpdfa-3)get)output_typemappings     r!   _pdfa_part_conformancerg      s*     	G ;;{J//rB   c                b    | j                         5 }||d<   ||d<   ddd       y# 1 sw Y   yxY w)zAdd PDF/A XMP metadata declaration to a PDF.

    Args:
        pdf: An open pikepdf.Pdf object
        part: PDF/A part number ('1', '2', or '3')
        conformance: Conformance level ('A', 'B', or 'U')
    zpdfaid:partzpdfaid:conformanceN)rS   )rD   partrG   metas       r!   add_pdfa_metadatark      s<     
			 1"]%0!"1 1 1s   %.c                ,   t               }t        | |      }d|t        j                  <   t	        t        j
                  t        d      d|d      }t        j                  | j                  vr&t        g       | j                  t        j                  <   | j                  j                  D ]D  }t        |j                  t        j                              dk(  s/t        j                  d        y | j                  j                  j                  |       y)aL  Add sRGB ICC profile as OutputIntent to PDF catalog.

    This creates the required PDF/A OutputIntent structure with:
    - An ICC profile stream containing sRGB profile
    - An OutputIntent dictionary pointing to that profile
    - Updates the Catalog's OutputIntents array

    Args:
        pdf: An open pikepdf.Pdf object
    r5   r%   r2   )r(   r)   r+   r*   z*sRGB OutputIntent already exists, skippingN)r^   r   r	   Nr   OutputIntentOutputIntentsRootr   r,   rd   OutputConditionIdentifierlogdebugappend)rD   r.   
icc_streamoutput_intentintents        r!   add_srgb_output_intentrx      s     &'H X&JJtvv ""< &,(	  M )',Ry##$ (((( vzz$889:fDIIBC
 HH!!-0rB   c                    t        |      \  }}t        j                  |       5 }t        |       t	        |||       |j                  |       ddd       t        j                  d|       |S # 1 sw Y   !xY w)a  Attempt to convert a PDF to PDF/A by adding required structures.

    This function creates a copy of the input PDF and adds:
    1. sRGB ICC profile as OutputIntent
    2. XMP metadata declaring PDF/A conformance

    This approach works for PDFs that are already mostly PDF/A compliant
    but lack the formal declarations. It does NOT perform color conversion,
    font embedding, or other transformations that Ghostscript does.

    Args:
        input_file: Path to input PDF
        output_file: Path where output PDF should be written
        output_type: One of 'pdfa', 'pdfa-1', 'pdfa-2', 'pdfa-3'

    Returns:
        Path to the output file

    Raises:
        pikepdf.PdfError: If the PDF cannot be opened or modified
    Nz)Speculative PDF/A conversion complete: %s)rg   r
   rR   rx   rk   saverr   rs   )
input_fileoutput_filere   ri   rG   rD   s         r!   speculative_pdfa_conversionr}      sm    4 /{;D+	*	 s##t[1	 II9;G s   *A..A7)
r   r,   r   zdict[str, str]r   z
str | Noner   zbytes | NonereturnIterator[str])r-   r,   r.   bytesr/   intr~   r   )r2   )r=   r   r>   r,   )rV   r   )r~   r   )re   r,   r~   ztuple[str, str])rD   r
   ri   r,   rG   r,   r~   None)rD   r
   r~   r   )r{   r   r|   r   re   r,   r~   r   )__doc__
__future__r   r   loggingcollections.abcr   importlib.resourcesr   r8   pathlibr   rQ   r   r   r	   r
   r   	getLogger__name__rr   r9   r"   r0   rA   r[   r^   rg   rk   rx   r}   r]   rB   r!   <module>r      s    H "   $ 6   8 8g!"  # $999 	9
 9 9:0#L6Q
0$
1#1L### # 
	#rB   