
    Wpf                        d Z ddlZddlZddlZddlZddlZddlZddlZddlZddl	Z	ddl
mZm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Zej        j        j        Zej        j        j        Zn # e $ rZ!e"Zej#        j        ZY dZ![!ndZ![!ww xY wd Z$dd
Z%d Z&d Z' e'd          Z( G d de)          Z* G d de*          Z+ G d de)          Z,de-de.fdZ/	 d deee.e.f                  de.fdZ0d Z1d Z2d Z3d Z4d Z5dS )!zTensorFlow Lite metadata tools.    N)DictOptional)_pywrap_metadata_version)metadata_schema_py_generated)schema_py_generated)_pywrap_flatbuffersc                 \    t          | d          r| S d|v r|n|dz   }t          | |          S )z4Maybe open the binary file, and returns a file-like.readb)hasattr
_open_file)filenamemodeopenmodes      h/var/www/html/nettyfy-visnx/env/lib/python3.11/site-packages/mediapipe/tasks/python/metadata/metadata.py_maybe_open_as_binaryr   2   s>    Xv OD[[TTdSj(	Hh	'	''    rc                 L    t          | |          }t          j        ||          S )zOpen file as a zipfile.

  Args:
    filename: str or file-like or path-like, to the zipfile.
    mode: str, common file mode for zip.
          (See: https://docs.python.org/3/library/zipfile.html)

  Returns:
    A ZipFile object.
  )r   zipfileZipFile)r   r   	file_likes      r   _open_as_zipfiler   :   s%     $Hd33)	D	)	))r   c                 ~    t          | d          5 }t          j        |          cddd           S # 1 swxY w Y   dS )zChecks whether it is a zipfile.r   N)r   r   
is_zipfile)r   fs     r   _is_zipfiler   I   s    Xs++ !qa  ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! !s   266c                     t           j                            t          j        t          j        d                              }t           j                            ||           S )a  Gets the path to the specified file in the data dependencies.

  The path is relative to the file calling the function.

  It's a simple replacement of
  "tensorflow.python.platform.resource_loader.get_path_to_datafile".

  Args:
    path: a string resource path relative to the calling file.

  Returns:
    The path to the specified file present in the data attribute of py_test
    or py_binary.
     )ospathdirnameinspectgetfilesys	_getframejoin)r!   data_files_paths     r   get_path_to_datafiler)   O   sA     GOOGOCM!4D4D$E$EFF/	ot	,	,,r   z"../../metadata/metadata_schema.fbsc                       e Zd ZdZdZdZdZd Zed             Z	ed             Z
d Zd	 Zd
 Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd ZdS )MetadataPopulatora3	  Packs metadata and associated files into TensorFlow Lite model file.

  MetadataPopulator can be used to populate metadata and model associated files
  into a model file or a model buffer (in bytearray). It can also help to
  inspect list of files that have been packed into the model or are supposed to
  be packed into the model.

  The metadata file (or buffer) should be generated based on the metadata
  schema:
  mediapipe/tasks/metadata/metadata_schema.fbs

  Example usage:
  Populate metadata and label file into an image classifier model.

  First, based on metadata_schema.fbs, generate the metadata for this image
  classifier model using Flatbuffers API. Attach the label file onto the output
  tensor (the tensor of probabilities) in the metadata.

  Then, pack the metadata and label file into the model as follows.

    ```python
    # Populating a metadata file (or a metadata buffer) and associated files to
    a model file:
    populator = MetadataPopulator.with_model_file(model_file)
    # For metadata buffer (bytearray read from the metadata file), use:
    # populator.load_metadata_buffer(metadata_buf)
    populator.load_metadata_file(metadata_file)
    populator.load_associated_files([label.txt])
    # For associated file buffer (bytearray read from the file), use:
    # populator.load_associated_file_buffers({"label.txt": b"file content"})
    populator.populate()

    # Populating a metadata file (or a metadata buffer) and associated files to
    a model buffer:
    populator = MetadataPopulator.with_model_buffer(model_buf)
    populator.load_metadata_file(metadata_file)
    populator.load_associated_files([label.txt])
    populator.populate()
    # Writing the updated model buffer into a file.
    updated_model_buf = populator.get_model_buffer()
    with open("updated_model.tflite", "wb") as f:
      f.write(updated_model_buf)

    # Transferring metadata and associated files from another TFLite model:
    populator = MetadataPopulator.with_model_buffer(model_buf)
    populator_dst.load_metadata_and_associated_files(src_model_buf)
    populator_dst.populate()
    updated_model_buf = populator.get_model_buffer()
    with open("updated_model.tflite", "wb") as f:
      f.write(updated_model_buf)
    ```

  Note that existing metadata buffer (if applied) will be overridden by the new
  metadata buffer.
  TFLITE_METADATAs   TFL3s   M001c                 N    t          |           || _        d| _        i | _        dS )zConstructor for MetadataPopulator.

    Args:
      model_file: valid path to a TensorFlow Lite model file.

    Raises:
      IOError: File not found.
      ValueError: the model does not have the expected flatbuffer identifier.
    N)_assert_model_file_identifier_model_file_metadata_buf_associated_files)self
model_files     r   __init__zMetadataPopulator.__init__   s0     "*---!DDDr   c                      | |          S )a=  Creates a MetadataPopulator object that populates data to a model file.

    Args:
      model_file: valid path to a TensorFlow Lite model file.

    Returns:
      MetadataPopulator object.

    Raises:
      IOError: File not found.
      ValueError: the model does not have the expected flatbuffer identifier.
     )clsr3   s     r   with_model_filez!MetadataPopulator.with_model_file   s     3z??r   c                      t          |          S )a>  Creates a MetadataPopulator object that populates data to a model buffer.

    Args:
      model_buf: TensorFlow Lite model buffer in bytearray.

    Returns:
      A MetadataPopulator(_MetadataPopulatorWithBuffer) object.

    Raises:
      ValueError: the model does not have the expected flatbuffer identifier.
    )_MetadataPopulatorWithBuffer)r7   	model_bufs     r   with_model_bufferz#MetadataPopulator.with_model_buffer   s     (	222r   c                     t          | j        d          5 }|                                cddd           S # 1 swxY w Y   dS )z}Gets the buffer of the model with packed metadata and associated files.

    Returns:
      Model buffer (in bytearray).
    rbN)r   r/   r
   )r2   r   s     r   get_model_bufferz"MetadataPopulator.get_model_buffer   s     
D$d	+	+ qVVXX                 s   7;;c                     t          | j                  sg S t          | j        d          5 }|                                cddd           S # 1 swxY w Y   dS )zsGets a list of associated files packed to the model file.

    Returns:
      List of packed associated files.
    r   N)r   r/   r   namelist)r2   zfs     r   get_packed_associated_file_listz1MetadataPopulator.get_packed_associated_file_list   s     t'(( i	$*C	0	0 B[[]]                 s   AAAc                     | j         sg S t          j                            t          j                            | j         d                    }d |                     |          D             S )zGets a list of associated files recorded in metadata of the model file.

    Associated files may be attached to a model, a subgraph, or an input/output
    tensor.

    Returns:
      List of recorded associated files.
    r   c                 B    g | ]}|j                             d           S )utf-8)namedecode).0files     r   
<listcomp>zGMetadataPopulator.get_recorded_associated_file_list.<locals>.<listcomp>   s8        		!!  r   )r0   _metadata_fbModelMetadataTInitFromObjModelMetadataGetRootAsModelMetadata)_get_recorded_associated_file_object_list)r2   metadatas     r   !get_recorded_associated_file_listz3MetadataPopulator.get_recorded_associated_file_list   sy      i*66"99	# 	#$ $H BB8LL   r   c                 r    | j                             d |                                D                        dS )a6  Loads the associated file buffers (in bytearray) to be populated.

    Args:
      associated_files: a dictionary of associated file names and corresponding
        file buffers, such as {"file.txt": b"file content"}. If pass in file
          paths for the file name, only the basename will be populated.
    c                 T    i | ]%\  }}t           j                            |          |&S r6   )r    r!   basename)rI   rG   bufferss      r   
<dictcomp>zBMetadataPopulator.load_associated_file_buffers.<locals>.<dictcomp>  s>     # # #D' 	# # #r   N)r1   updateitems)r2   associated_filess     r   load_associated_file_buffersz.MetadataPopulator.load_associated_file_buffers  sQ     	!! # #-3355# # #     r   c                     |D ]b}t          |           t          |d          5 }|                     ||                                i           ddd           n# 1 swxY w Y   cdS )zLoads associated files that to be concatenated after the model file.

    Args:
      associated_files: list of file paths.

    Raises:
      IOError:
        File not found.
    r>   N)_assert_file_existr   r\   r
   )r2   r[   af_nameafs       r   load_associated_filesz'MetadataPopulator.load_associated_files  s     $ @ @!!!gt$$ @))7BGGII*>???@ @ @ @ @ @ @ @ @ @ @ @ @ @ @@ @s   *AA	!A	c                     |st          d          |                     |           t          j        t	          |                    }t
          j                            t
          j        	                    |d                    }||_
        |                     |           t          j        d          }|                    |                    |          | j                   |                                }|| _        dS )a  Loads the metadata buffer (in bytearray) to be populated.

    Args:
      metadata_buf: metadata buffer (in bytearray) to be populated.

    Raises:
      ValueError: The metadata to be populated is empty.
      ValueError: The metadata does not have the expected flatbuffer identifier.
      ValueError: Cannot get minimum metadata parser version.
      ValueError: The number of SubgraphMetadata is not 1.
      ValueError: The number of input/output tensors does not match the number
        of input/output tensor metadata.
    z&The metadata to be populated is empty.r   N)
ValueError_validate_metadatar   GetMinimumMetadataParserVersionbytesrL   rM   rN   rO   rP   minParserVersion._use_basename_for_associated_files_in_metadataflatbuffersBuilderFinishPackMETADATA_FILE_IDENTIFIEROutputr0   )r2   metadata_bufmin_versionrR   r   metadata_buf_with_versions         r   load_metadata_bufferz&MetadataPopulator.load_metadata_buffer!  s      A?@@@L))) +Jl K *66"99,JJL LH +H 	77AAAAAHHX]]1t<=== !

2Dr   c                     t          |           t          |d          5 }|                                }ddd           n# 1 swxY w Y   |                     t	          |                     dS )a  Loads the metadata file to be populated.

    Args:
      metadata_file: path to the metadata file to be populated.

    Raises:
      IOError: File not found.
      ValueError: The metadata to be populated is empty.
      ValueError: The metadata does not have the expected flatbuffer identifier.
      ValueError: Cannot get minimum metadata parser version.
      ValueError: The number of SubgraphMetadata is not 1.
      ValueError: The number of input/output tensors does not match the number
        of input/output tensor metadata.
    r>   N)r^   r   r
   rr   	bytearray)r2   metadata_filer   ro   s       r   load_metadata_filez$MetadataPopulator.load_metadata_fileG  s     }%%%	M4	(	( AVVXXl              i5566666s   AAAc                 t   t          |          }|r|                     |           t          t          j        |                    rot          t          j        |                    5 |                     fd                                D                        ddd           dS # 1 swxY w Y   dS dS )zLoads the metadata and associated files from another model buffer.

    Args:
      src_model_buf: source model buffer (in bytearray) with metadata and
        associated files.
    c                 <    i | ]}|                     |          S r6   )r
   )rI   r   rB   s     r   rX   zHMetadataPopulator.load_metadata_and_associated_files.<locals>.<dictcomp>k  s%    222qQ

222r   N)get_metadata_bufferrr   r   ioBytesIOr   r\   rA   )r2   src_model_bufmetadata_bufferrB   s      @r   "load_metadata_and_associated_filesz4MetadataPopulator.load_metadata_and_associated_files[  s    *-88O 1
000 2:m,,-- 4BJ}5566 4"))2222BKKMM222	4 	4 	44 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 44 4s   *4B++B/2B/c                 ~    |                                   |                                  |                                  dS )zCPopulates loaded metadata and associated files into the model file.N)_assert_validate_populate_metadata_buffer_populate_associated_filesr2   s    r   populatezMetadataPopulator.populatem  s>    ""$$$##%%%%%r   c                    |                                  }|                                 }| j                                        }|D ],}||vr&||vr"t	          d                    |                    -|D ]S}||v r"t	          d                    |                    ||vr't          j        d                    |                     TdS )zValidates the metadata and associated files to be populated.

    Raises:
      ValueError:
        File is recorded in the metadata, but is not going to be populated.
        File has already been packed.
    zUFile, '{0}', is recorded in the metadata, but has not been loaded into the populator.z%File, '{0}', has already been packed.z]File, '{0}', does not exist in the metadata. But packing it to tflite model is still allowed.N)rS   rC   r1   keysrc   formatwarningswarn)r2   recorded_filespacked_filesto_be_populated_filesrfr   s         r   r   z"MetadataPopulator._assert_validates  s    ;;==N 7799L !27799  K K	(	(	(R|-C-C ??EvbzzK K 	K # 8 8	
l		@GGJJKKK	
.	 	 --3VAYY	8 	8 	88 8r   c           	         t          |          s"t          d                    |                    t          |d          5 }t          |d          5 }|                                }|D ]T}||vr#t          d                    ||                    |                    |          }|                    ||           U	 ddd           n# 1 swxY w Y   ddd           dS # 1 swxY w Y   dS )z:Copy archieved files in file_list from src_zip ro dst_zip.zFile, '{0}', is not a zipfile.r   az0File, '{0}', does not exist in the zipfile, {1}.N)r   rc   r   r   rA   r
   writestr)	r2   src_zip	file_listdst_zipsrc_zfdst_zfsrc_listr   file_buffers	            r   _copy_archived_filesz&MetadataPopulator._copy_archived_files  s    w I7>>wGGHHH	'3	'	' 	(6	'3	'	'	(+1""h ( (!H@GGW    kk!nn;''''(	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	(s7   C$A,C C$C	C$C	C$$C(+C(c                 f   |g S g }t          ||          }|pg D ]}|j        }t          |t          j        t          j        f          r||                     |d          z  }It          |t          j                  r2||                     |d          z  }||                     |d          z  }|S )a9  Gets the files that are attached the process units field of a table.

    Args:
      table: a Flatbuffers table object that contains fields of an array of
        ProcessUnit, such as TensorMetadata and SubGraphMetadata.
      field_name: the name of the field in the table that represents an array of
        ProcessUnit. If the table is TensorMetadata, field_name can be
        "ProcessUnits". If the table is SubGraphMetadata, field_name can be
        either "InputProcessUnits" or "OutputProcessUnits".

    Returns:
      A list of AssociatedFileT objects.
    N	vocabFilesentencePieceModel)getattroptions
isinstancerL   BertTokenizerOptionsTRegexTokenizerOptionsT _get_associated_files_from_tableSentencePieceTokenizerOptionsT)r2   table
field_namer   process_unitsprocess_unitr   s          r   (_get_associated_files_from_process_unitsz:MetadataPopulator._get_associated_files_from_process_units  s     }iIE:..M &+ Q Q$g	Gl@*AC 
D 
D QT::7KPPP		g|JKK QT::)+ + 	+	T::7KPPP	r   c                 .    |g S t          ||          pg S )a  Gets the associated files that are attached a table directly.

    Args:
      table: a Flatbuffers table object that contains fields of an array of
        AssociatedFile, such as TensorMetadata and BertTokenizerOptions.
      field_name: the name of the field in the table that represents an array of
        ProcessUnit. If the table is TensorMetadata, field_name can be
        "AssociatedFiles". If the table is BertTokenizerOptions, field_name can
        be "VocabFile".

    Returns:
      A list of AssociatedFileT objects.
    )r   )r2   r   r   s      r   r   z2MetadataPopulator._get_associated_files_from_table  s%     }i 5*%%++r   c                    g }||                      |d          z  }|j        pg D ]}||                      |d          z  }|j        pg D ]4}||                      |d          z  }||                     |d          z  }5|j        pg D ]4}||                      |d          z  }||                     |d          z  }5||                     |d          z  }||                     |d          z  }|S )a  Gets a list of AssociatedFileT objects recorded in the metadata.

    Associated files may be attached to a model, a subgraph, or an input/output
    tensor.

    Args:
      metadata: the ModelMetadataT object.

    Returns:
      List of recorded AssociatedFileT objects.
    associatedFilesprocessUnitsinputProcessUnitsoutputProcessUnits)r   subgraphMetadatainputTensorMetadatar   outputTensorMetadata)r2   rR   r   subgraphtensor_metadatas        r   rQ   z;MetadataPopulator._get_recorded_associated_file_object_list  sv    N d;;#% % %N -3 * *==
%' ' 'n &9?R - -/$??.0 0 	0$GG^- - 	- &:@b - -/$??.0 0 	0$GG^- - 	- EE
') ) )n EE
(* * *nn r   c                 L   t          j                    5 }t          | j        d          5 }t	          j        ||           ddd           n# 1 swxY w Y   t          |d          5 }| j                                        D ]\  }}|	                    ||           	 ddd           n# 1 swxY w Y   |
                    d           t          | j        d          5 }t	          j        ||           ddd           n# 1 swxY w Y   ddd           dS # 1 swxY w Y   dS )zConcatenates associated files after TensorFlow Lite model file.

    If the MetadataPopulator object is created using the method,
    with_model_file(model_file), the model file will be updated.
    r>   Nr   r   wb)tempfileSpooledTemporaryFiler   r/   shutilcopyfileobjr   r1   rZ   r   seek)r2   tempr   rB   	file_namer   s         r   r   z,MetadataPopulator._populate_associated_files
  s    
	&	(	( $Dd&-- $1d###$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ D#&& ."&*&<&B&B&D&D 	. 	."I{
++i
-
-
-
-	.. . . . . . . . . . . . . . .
 iillld&-- $4###$ $ $ $ $ $ $ $ $ $ $ $ $ $ $$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $s|   DA DA	DA	D'6B*D*B.	.D1B.	2-DD5DD	DD		DD Dc                    t          | j        d          5 }|                                }ddd           n# 1 swxY w Y   t          j                            t          j                            |d                    }t          j                    }| j	        |_
        d}|j        sg |_        n>|j        D ]6}|j                            d          | j        k    rd}||j        |j        <   7|s}|j        sg |_        |j                            |           t          j                    }| j        |_        t'          |j                  dz
  |_        |j                            |           t)          j        d          }|                    |                    |          | j                   |                                }|                                 }	|	rt7          j                    5 }
|
                    |           |                     | j        |	|
           |
                    d           t          | j        d          5 }tA          j!        |
|           ddd           n# 1 swxY w Y   ddd           dS # 1 swxY w Y   dS t          | j        d          5 }|                    |           ddd           dS # 1 swxY w Y   dS )	ai  Populates the metadata buffer (in bytearray) into the model file.

    Inserts metadata_buf into the metadata field of schema.Model. If the
    MetadataPopulator object is created using the method,
    with_model_file(model_file), the model file will be updated.

    Existing metadata buffer (if applied) will be overridden by the new metadata
    buffer.
    r>   Nr   FrF   Tr   r   )"r   r/   r
   
_schema_fbModelTrN   ModelGetRootAsModelBufferTr0   datarR   rG   rH   METADATA_FIELD_NAMErW   bufferappend	MetadataTlenri   rj   rk   rl   TFLITE_FILE_IDENTIFIERrn   rC   r   r   writer   r   r   r   )r2   r   r;   modelbuffer_fieldis_populatedmetametadata_fieldr   r   r   s              r   r   z+MetadataPopulator._populate_metadata_buffer%  s    
D$d	+	+ q&&((i               ))''	1557 7E%''L*LL> 4enn . 4 4$9G$$(@@@,'3%-
$ ,] m<(((!+--n 4n!%-0014nnN+++ 	AAHHUZZ]]D7888

I 7799L  (** &d

9!!$"2L$GGG		!($// 	&1

T1
%
%
%	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	&	& & & & & & & & & & & & & & & & & & d&-- 		                 sU   7;;+AJI)J)I-	-J0I-	1JJJ#KK
K
c                     |                      |          D ]+}t          j                            |j                  |_        ,dS )z8Removes any associated file local directory (if exists).N)rQ   r    r!   rV   rG   )r2   rR   rJ   s      r   rh   z@MetadataPopulator._use_basename_for_associated_files_in_metadataa  sD    >>xHH . .'""49--dii. .r   c                    t          |           t          j                            |d          }|                                dk    r4t          d                    |                                                    t          | j        d          5 }|	                                }ddd           n# 1 swxY w Y   t          j                            |d          }|                    d                                          }|                    d                                          }||k    r#t          d                    ||                    |                    d                                          }|                    d                                          }	||	k    r#t          d                    ||	                    dS )z'Validates the metadata to be populated.r   r   zBThe number of SubgraphMetadata should be exactly one, but got {0}.r>   NzXThe number of input tensors ({0}) should match the number of input tensor metadata ({1})zZThe number of output tensors ({0}) should match the number of output tensor metadata ({1}))"_assert_metadata_buffer_identifierrL   rO   rP   SubgraphMetadataLengthrc   r   r   r/   r
   r   r   r   	SubgraphsInputsLengthSubgraphMetadataInputTensorMetadataLengthOutputsLengthOutputTensorMetadataLength)
r2   ro   
model_metar   r;   r   num_input_tensorsnum_input_metanum_output_tensorsnum_output_metas
             r   rd   z$MetadataPopulator._validate_metadataf  s   &|444 +BBa J((**a// &&,f%<<>>'@ '@A A A
 
D$d	+	+ q&&((i              ++Iq99E**77990033MMOONN**((./@/=)? )?@ @ @ ++99;; 11	 %%'' _,,))/0B0?*A *AB B B -,s   B22B69B6N)__name__
__module____qualname____doc__r   r   rm   r4   classmethodr8   r<   r?   rC   rS   r\   ra   rr   rv   r~   r   r   r   r   r   rQ   r   r   rh   rd   r6   r   r   r+   r+   g   s       6 6z *"$         ;" 3 3 ;3  
 
 
  *  @ @ @$3 $3 $3L7 7 7(4 4 4$& & &8 8 8@( ( ("  B, , ,,- - -^$ $ $6: : :x. . .
 B  B  B  B  Br   r+   c                   (     e Zd ZdZ fdZd Z xZS )r:   a  Subclass of MetadataPopulator that populates metadata to a model buffer.

  This class is used to populate metadata into a in-memory model buffer. As we
  use Zip API to concatenate associated files after tflite model file, the
  populating operation is developed based on a model file. For in-memory model
  buffer, we create a tempfile to serve the populating operation. This class is
  then used to generate this tempfile, and delete the file when the
  MetadataPopulator object is deleted.
  c                 J   |st          d          t          j                    5 }|j        }ddd           n# 1 swxY w Y   t	          |d          5 }|                    |           ddd           n# 1 swxY w Y   t                                          |           dS )zConstructor for _MetadataPopulatorWithBuffer.

    Args:
      model_buf: TensorFlow Lite model buffer in bytearray.

    Raises:
      ValueError: model_buf is empty.
      ValueError: model_buf does not have the expected flatbuffer identifier.
    zmodel_buf cannot be empty.Nr   )rc   r   NamedTemporaryFilerG   r   r   superr4   )r2   r;   r   r3   r   	__class__s        r   r4   z%_MetadataPopulatorWithBuffer.__init__  s     53444		$	&	& $9j               
J	%	% ggi               
GGZ     s   :>>A77A;>A;c                     t           j                            | j                  rt          j        | j                   dS dS )zKDestructor of _MetadataPopulatorWithBuffer.

    Deletes the tempfile.
    N)r    r!   existsr/   remover   s    r   __del__z$_MetadataPopulatorWithBuffer.__del__  s@    
 
w~~d&'' "i !!!!!" "r   )r   r   r   r   r4   r   __classcell__)r   s   @r   r:   r:     sQ         ! ! ! ! !*" " " " " " "r   r:   c                   r    e Zd ZdZd Zed             Zed             Zd Zd Z	d Z
d Zed	             Zd
S )MetadataDisplayerzDDisplays metadata and associated file info in human-readable format.c                 l    t          |           t          |           || _        || _        || _        dS )zConstructor for MetadataDisplayer.

    Args:
      model_buffer: valid buffer of the model file.
      metadata_buffer: valid buffer of the metadata file.
      associated_file_list: list of associate files in the model file.
    N)_assert_model_buffer_identifierr   _model_buffer_metadata_buffer_associated_file_list)r2   model_bufferr}   associated_file_lists       r   r4   zMetadataDisplayer.__init__  s>     $L111&777%D+D!5Dr   c                     t          |           t          |d          5 }|                     |                                          cddd           S # 1 swxY w Y   dS )a  Creates a MetadataDisplayer object for the model file.

    Args:
      model_file: valid path to a TensorFlow Lite model file.

    Returns:
      MetadataDisplayer object.

    Raises:
      IOError: File not found.
      ValueError: The model does not have metadata.
    r>   N)r^   r   r<   r
   )r7   r3   r   s      r   r8   z!MetadataDisplayer.with_model_file  s     z"""	J	%	% -""16688,,- - - - - - - - - - - - - - - - - -s   'AAAc                     |st          d          t          |          }|st          d          |                     |          } | |||          S )zCreates a MetadataDisplayer object for a file buffer.

    Args:
      model_buffer: TensorFlow Lite model buffer in bytearray.

    Returns:
      MetadataDisplayer object.
    zmodel_buffer cannot be empty.z!The model does not have metadata.)rc   ry   "_parse_packed_associated_file_list)r7   r   r}   r   s       r   r<   z#MetadataDisplayer.with_model_buffer  sh      86777),77O <:;;;AA,OO3|_.BCCCr   c                    || j         vr"t          d                    |                    t          t	          j        | j                            5 }|                    |          cddd           S # 1 swxY w Y   dS )zGet the specified associated file content in bytearray.

    Args:
      filename: name of the file to be extracted.

    Returns:
      The file content in bytearray.

    Raises:
      ValueError: if the file does not exist in the model.
    z*The file, {}, does not exist in the model.N)r   rc   r   r   rz   r{   r   r
   )r2   r   rB   s      r   get_associated_file_bufferz,MetadataDisplayer.get_associated_file_buffer  s     t111
6
=
=h
G
GI I I 
"*T%788	9	9 RWWX                 s   A44A8;A8c                 4    t          j        | j                  S )z8Get the metadata buffer in bytearray out from the model.)copydeepcopyr   r   s    r   ry   z%MetadataDisplayer.get_metadata_buffer  s    =.///r   c                 *    t          | j                  S )z)Converts the metadata into a json string.)convert_to_jsonr   r   s    r   get_metadata_jsonz#MetadataDisplayer.get_metadata_json  s    40111r   c                 4    t          j        | j                  S )zzReturns a list of associated files that are packed in the model.

    Returns:
      A name list of associated files.
    )r   r   r   r   s    r   rC   z1MetadataDisplayer.get_packed_associated_file_list  s     =3444r   c                     	 t          t          j        |                    5 }|                                cddd           S # 1 swxY w Y   dS # t          j        $ r g cY S w xY w)zGets a list of associated files packed to the model file.

    Args:
      model_buf: valid file buffer.

    Returns:
      List of packed associated files.
    N)r   rz   r{   rA   r   
BadZipFile)r7   r;   rB   s      r   r   z4MetadataDisplayer._parse_packed_associated_file_list
  s    BJy1122 b{{}}                    iiis3   !A AA AA AA A%$A%N)r   r   r   r   r4   r   r8   r<   r   ry   r   rC   r   r6   r   r   r   r     s        LL6 6 6 - - ;-" D D ;D"  &0 0 02 2 25 5 5   ;  r   r   r}   rG   c                    t           j                            |           }|                    d          }||                                rdS t          |                                          D ]l}|                    |          }|                                	                    d          |k    r*||
                                                                fc S mdS )a#  Gets the custom metadata in metadata_buffer based on the name.

  Args:
    metadata_buffer: valid metadata buffer in bytes.
    name: custom metadata name.

  Returns:
    Index of custom metadata, custom metadata flatbuffer. Returns (None, None)
    if the custom metadata is not found.
  r   N)NNrF   )rL   rO   	GetRootAsr   CustomMetadataIsNonerangeCustomMetadataLengthCustomMetadataNamerH   DataAsNumpytobytes)r}   rG   model_metadatar   icustom_metadatas         r   _get_custom_metadatar    s      -77HH.,,Q//(6688:..0011 8 8a--a00O$$W--55++--55777777 6	r   custom_metadata_schemareturnc                    t          j                    }d|_        t          j        |          }t	          t
                    5 }|                                }ddd           n# 1 swxY w Y   |                    |          st          d|j	        z             t          j
        ||           }|s|S t          j        |          }|                                D ]\  }}	t          | |          \  }
}|st          j        d|           0t#          |	           t	          |	d          5 }|                                }ddd           n# 1 swxY w Y   |                    |          st          d|j	        z             t          j
        ||          }|d         d         d	         |
         }||d
<   t          j        |          |d<   t          j        |d          S )a  Converts the metadata into a json string.

  Args:
    metadata_buffer: valid metadata buffer in bytes.
    custom_metadata_schema: A dict of custom metadata schema, in which key is
      custom metadata name [1], value is the filepath that defines custom
      metadata schema. For instance, custom_metadata_schema =
      {"SEGMENTER_METADATA": "metadata/vision_tasks_metadata_schema.fbs"}. [1]:
        https://github.com/google/mediapipe/blob/46b5c4012d2ef76c9d92bb0d88a6b107aee83814/mediapipe/tasks/metadata/metadata_schema.fbs#L612

  Returns:
    Metadata in JSON format.

  Raises:
    ValueError: error occurred when parsing the metadata schema file.
  TNz&Cannot parse metadata schema. Reason: z7No custom metadata with name %s in metadata flatbuffer.r>   z-Cannot parse custom metadata schema. Reason: subgraph_metadatar   r  rG   r      )indent)r   
IDLOptionsstrict_jsonParserr   "_FLATC_TFLITE_METADATA_SCHEMA_FILEr
   parserc   errorgenerate_textjsonloadsrZ   r  logginginfor^   dumps)r}   r  optparserr   metadata_schema_contentraw_json_content	json_datarG   schema_fileidxr  custom_metadata_schema_contentcustom_metadata_json	json_metas                  r   r   r   5  sn   & 	&((##/%c**&455 'ffhh' ' ' ' ' ' ' ' ' ' ' ' ' ' '	-	.	. N
=L
M
MM(6vOO	 j)**) 27799 9 9dK/FFC l
CT   {###	K	&	& 0!'(vvxx$0 0 0 0 0 0 0 0 0 0 0 0 0 0 0<<677 
9FL
H   /<  -.q12CDSIIIf
#788If	Ia	(	(	((s$   A$$A(+A(+EE	E	c                 h    t          |           s"t          d                    |                     dS )zChecks if a file exists.zFile, '{0}', does not exist.N)_exists_fileIOErrorr   )r   s    r   r^   r^   n  s<    	h		 C
077AA
B
BBC Cr   c                     t          |            t          | d          5 }t          |                                           ddd           dS # 1 swxY w Y   dS )zAChecks if a model file has the expected TFLite schema identifier.r>   N)r^   r   r   r
   )r3   r   s     r   r.   r.   t  s    Z   *d## .q#AFFHH---. . . . . . . . . . . . . . . . . .s   "AAAc                 d    t           j                            | d          st          d          d S )Nr   z^The model provided does not have the expected identifier, and may not be a valid TFLite model.)r   r   ModelBufferHasIdentifierrc   )r;   s    r   r   r   {  s>    			2	29a	@	@ ,
	+, , ,, ,r   c                 d    t           j                            | d          st          d          dS )zHChecks if a metadata buffer has the expected Metadata schema identifier.r   zbThe metadata buffer does not have the expected identifier, and may not be a valid TFLite Metadata.N)rL   rO    ModelMetadataBufferHasIdentifierrc   )ro   s    r   r   r     sC    		#	D	DA
 
 (
	'( ( (( (r   c                    t           j                            | d          }t          |                                          D ]}|                    |          }|                                                    d          t          j	        k    rj|
                                }|                    |          }|                                dk    r|                                                                c S dS )zReturns the metadata in the model file as a buffer.

  Args:
    model_buf: valid buffer of the model file.

  Returns:
    Metadata buffer. Returns `None` if the model does not have metadata.
  r   rF   N)r   r   r   r  MetadataLengthMetadatar
  rH   r+   r   BufferBuffers
DataLengthr  r  )r;   tflite_modelr  r   buffer_indexrR   s         r   ry   ry     s     !00A>>, ,,..// . .a  ##Dyy{{'""&7&KKK[[]]l%%l33h					!	#	#!!##++----- L 
r   )r   )N)6r   r   r#   rz   r  r   r    r   r%   r   typingr   r   r   r   ri   "mediapipe.tasks.cc.metadata.pythonr   mediapipe.tasks.metadatar   rL   r   r   /mediapipe.tasks.python.metadata.flatbuffers_libr   
tensorflowtfgfileGFiler   r   r.  ImportErroreopenr!   r   r   r   r)   r  objectr+   r:   r   rf   strr  r   r^   r.   r   r   ry   r6   r   r   <module>rJ     s   & %   				   				  



  ! ! ! ! ! ! ! !       G G G G G G Q Q Q Q Q Q F F F F F F O O O O O O
  u{ *#,,      *,,,,,, ( ( (* * * *! ! !- - -& &:%9(&* &* "
_B _B _B _B _B _B _B _BD&" &" &" &" &"#4 &" &" &"Rg g g g g g g gT% s    4 IM6) 6)-5d38n-E6)6) 6) 6) 6)rC C C. . ., , ,( ( (    s   &A; ;B BB