char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
f45576aa8
char/aliceai-t5-moe
1#ifndef MTMD_H 2#define MTMD_H 3 4#include "ggml.h" 5#include "llama.h" 6 7#include <stddef.h> 8#include <stdint.h> 9#include <stdbool.h> 10 11#ifdef __cplusplus 12#include <map> 13#include <string> 14#include <vector> 15#include <cinttypes> 16#include <memory> 17#endif 18 19/** 20* libmtmd: A library for multimodal support in llama.cpp. 21* 22* WARNING: This API is experimental and subject to many BREAKING CHANGES. 23* Issues related to API usage may receive lower priority support. 24* 25* For the usage, see an example in mtmd-cli.cpp 26* 27* For contributors: 28* - Make sure the C API is aligned with the libllama C API (as in llama.h) 29* - Do not include model name (e.g., qwen, gemma) in the API, use generic terms instead 30* - Keep the API minimal, do not expose internal details unless necessary 31* 32* IMPORTANT: The mtmd module does NOT accept pull requests that are fully or predominantly AI-generated. 33* We encourage human contributors to ensure the quality and reliability of the codebase. 34*/ 35 36#ifdef LLAMA_SHARED 37# if defined(_WIN32 )&& !defined(__MINGW32__ ) 38# ifdef LLAMA_BUILD 39# define MTMD_API __declspec(dllexport) 40# else 41# define MTMD_API __declspec(dllimport) 42# endif 43# else 44# define MTMD_API __attribute__ ((visibility ("default"))) 45# endif 46#else 47# define MTMD_API 48#endif 49 50#ifdef __cplusplus 51extern "C" { 52#endif 53 54enum mtmd_input_chunk_type { 55MTMD_INPUT_CHUNK_TYPE_TEXT , 56MTMD_INPUT_CHUNK_TYPE_IMAGE , 57MTMD_INPUT_CHUNK_TYPE_AUDIO , 58MTMD_INPUT_CHUNK_TYPE_COUNT ,// for validation 59}; 60 61// opaque types 62struct mtmd_context ; 63struct mtmd_bitmap ; 64struct mtmd_image_tokens ; 65struct mtmd_input_chunk ; 66struct mtmd_input_chunks ; 67struct mtmd_batch ; 68 69struct mtmd_input_text { 70const char * text ; 71size_t text_len ; 72bool add_special ; 73bool parse_special ; 74}; 75 76struct mtmd_input_part { 77// only text or bitmap can be set, not both 78const struct mtmd_input_text * text ; 79const struct mtmd_bitmap * bitmap ; 80}; 81 82// 83// C API 84// 85 86typedef struct mtmd_context mtmd_context ; 87typedef struct mtmd_bitmap mtmd_bitmap ; 88typedef struct mtmd_image_tokens mtmd_image_tokens ; 89typedef struct mtmd_input_chunk mtmd_input_chunk ; 90typedef struct mtmd_input_chunks mtmd_input_chunks ; 91typedef struct mtmd_input_text mtmd_input_text ; 92typedef struct mtmd_input_part mtmd_input_part ; 93typedef struct mtmd_batch mtmd_batch ; 94 95typedef bool (* mtmd_progress_callback )(float progress ,void * user_data ); 96 97struct mtmd_context_params { 98bool use_gpu ; 99ggml_backend_dev_t device ; 100bool print_timings ; 101int n_threads ; 102const char * image_marker ;// deprecated, use media_marker instead 103const char * media_marker ; 104enum llama_flash_attn_type flash_attn_type ; 105bool warmup ;// whether to run a warmup encode pass after initialization 106 107// limit number of image tokens, only for vision models with dynamic resolution 108int image_min_tokens ;// minimum number of tokens for image input (default: read from metadata) 109int image_max_tokens ;// maximum number of tokens for image input (default: read from metadata) 110 111// callback function passed over to mtmd proper 112ggml_backend_sched_eval_callback cb_eval ; 113void * cb_eval_user_data ; 114 115// batching params 116int32_t batch_max_tokens ;// maximum number of output tokens in a batch 117// (note: this is not a hard-limit, the first image will always be added even if it exceeds this limit) 118// (default: 1024) 119 120// Called with a progress value between 0.0 and 1.0. Pass NULL to disable. 121// If the provided progress_callback returns true, model loading continues. 122// If it returns false, model loading is immediately aborted. 123mtmd_progress_callback progress_callback ; 124void * progress_callback_user_data ; 125}; 126 127MTMD_API const char * mtmd_default_marker (void ); 128 129MTMD_API struct mtmd_context_params mtmd_context_params_default (void ); 130 131// initialize the mtmd context 132// return nullptr on failure 133MTMD_API mtmd_context * mtmd_init_from_file (const char * mmproj_fname , 134const struct llama_model * text_model , 135const struct mtmd_context_params ctx_params ); 136 137MTMD_API void mtmd_free (mtmd_context * ctx ); 138 139// whether we need to set non-causal mask before llama_decode 140// if chunk is nullptr, we assume the default case where chunk is an image chunk 141MTMD_API bool mtmd_decode_use_non_causal (const mtmd_context * ctx ,const mtmd_input_chunk * chunk ); 142 143// whether the current model use M-RoPE for llama_decode 144MTMD_API bool mtmd_decode_use_mrope (const mtmd_context * ctx ); 145 146// whether the current model supports vision input 147MTMD_API bool mtmd_support_vision (const mtmd_context * ctx ); 148 149// whether the current model supports audio input 150MTMD_API bool mtmd_support_audio (const mtmd_context * ctx ); 151 152// get audio sample rate in Hz, for example 16000 for Whisper 153// return -1 if audio is not supported 154MTMD_API int mtmd_get_audio_sample_rate (const mtmd_context * ctx ); 155 156// get the current marker string 157MTMD_API const char * mtmd_get_marker (const mtmd_context * ctx ); 158 159// mtmd_bitmap 160// 161// if bitmap is image: 162// length of data must be nx * ny * 3 163// the data is in RGBRGBRGB... format 164// note: some video-capable models (i.e. qwen-vl) can merge consecutive bitmaps 165// into one chunk; mtmd_tokenize() handles this, but remember to set 166// mtmd_bitmap_set_mergeable(true) for every frame 167// if bitmap is audio: 168// length of data must be n_samples * sizeof(float) 169// the data is in float format (PCM F32) 170// 171// if data == nullptr: 172// the bitmap is considered "empty", and will be treated as a placeholder for counting tokens 173// you can pass the bitmap via mtmd_tokenize(), then call mtmd_*_get_n_tokens() to count the tokens 174// note: passing a placeholder bitmap to mtmd_encode() will return an error 175MTMD_API mtmd_bitmap * mtmd_bitmap_init (uint32_t nx ,uint32_t ny ,const unsigned char * data ); 176MTMD_API mtmd_bitmap * mtmd_bitmap_init_from_audio (size_t n_samples ,const float * data ); 177MTMD_API uint32_t mtmd_bitmap_get_nx (const mtmd_bitmap * bitmap ); 178MTMD_API uint32_t mtmd_bitmap_get_ny (const mtmd_bitmap * bitmap ); 179MTMD_API const unsigned char * mtmd_bitmap_get_data (const mtmd_bitmap * bitmap ); 180MTMD_API size_t mtmd_bitmap_get_n_bytes (const mtmd_bitmap * bitmap ); 181MTMD_API bool mtmd_bitmap_is_audio (const mtmd_bitmap * bitmap ); 182MTMD_API void mtmd_bitmap_free (mtmd_bitmap * bitmap ); 183// bitmap ID is optional, but useful for KV cache tracking 184// these getters/setters are dedicated functions, so you can for example calculate the hash of the image based on mtmd_bitmap_get_data() 185MTMD_API const char * mtmd_bitmap_get_id (const mtmd_bitmap * bitmap ); 186MTMD_API void mtmd_bitmap_set_id (mtmd_bitmap * bitmap ,const char * id ); 187// if true, this bitmap can be merged (temporal merge) with an adjacent mergeable bitmap by certain video input models 188MTMD_API void mtmd_bitmap_set_mergeable (mtmd_bitmap * bitmap ,bool mergeable ); 189 190// mtmd_bitmap lazy 191// 192// this is a special bitmap that: 193// - does not hold the actual data 194// - can be expanded into one or more chunks (either media to text chunks) 195// user must provide a callback to fill in the data when mtmd_tokenize() is called 196// this is useful for large video inputs: 197// - allow reading video frame by frame, without loading the entire video into memory 198// - allow tracking the whole video with a single ID (for example, the file hash) 199 200// set (*out_bitmap) to non-nullptr to emit a bitmap chunk; it will be freed automatically 201// set (*out_text) to non-nullptr to emit a text chunk; it must be heap-allocated, null-terminated and will be freed automatically 202// either out_bitmap or out_text can be set, but not both 203// out_bitmap cannot be another lazy bitmap (no nested lazy allowed) 204// return value: 205// 0 on success 206// -1 on EOF (signal to mtmd_tokenize to move on) 207// -2 on error (signal to mtmd_tokenize to abort) 208typedef int (* mtmd_bitmap_lazy_callback )( 209size_t chunk_idx , 210void * user_data , 211mtmd_bitmap ** out_bitmap , 212char ** out_text ); 213 214MTMD_API mtmd_bitmap * mtmd_bitmap_init_lazy (const mtmd_context * ctx , 215const char * id ,// usually set to file hash 216void * user_data , 217mtmd_bitmap_lazy_callback callback ); 218 219// mtmd_input_chunks 220// 221// this is simply a list of mtmd_input_chunk 222// the elements can only be populated via mtmd_tokenize() 223MTMD_API mtmd_input_chunks * mtmd_input_chunks_init (void ); 224MTMD_API size_t mtmd_input_chunks_size (const mtmd_input_chunks * chunks ); 225MTMD_API const mtmd_input_chunk * mtmd_input_chunks_get (const mtmd_input_chunks * chunks ,size_t idx ); 226MTMD_API void mtmd_input_chunks_free (mtmd_input_chunks * chunks ); 227 228// mtmd_input_chunk 229// 230// the instance will be constructed via mtmd_tokenize() 231// it will be freed along with mtmd_input_chunks 232MTMD_API enum mtmd_input_chunk_type mtmd_input_chunk_get_type (const mtmd_input_chunk * chunk ); 233MTMD_API const llama_token * mtmd_input_chunk_get_tokens_text (const mtmd_input_chunk * chunk ,size_t * n_tokens_output ); 234MTMD_API const mtmd_image_tokens * mtmd_input_chunk_get_tokens_image (const mtmd_input_chunk * chunk ); 235MTMD_API size_t mtmd_input_chunk_get_n_tokens (const mtmd_input_chunk * chunk ); 236// returns nullptr for ID on text chunk 237MTMD_API const char * mtmd_input_chunk_get_id (const mtmd_input_chunk * chunk ); 238// number of temporal positions (equals to max(t,h,w) for M-RoPE; equals to n_tokens otherwise) 239MTMD_API llama_pos mtmd_input_chunk_get_n_pos (const mtmd_input_chunk * chunk ); 240 241// in case you want to use custom logic to handle the chunk (i.e. KV cache management) 242// you can move the chunk ownership to your own code by copying it 243// remember to free the chunk when you are done with it 244MTMD_API mtmd_input_chunk * mtmd_input_chunk_copy (const mtmd_input_chunk * chunk ); 245MTMD_API void mtmd_input_chunk_free (mtmd_input_chunk * chunk ); 246 247// similar to mtmd_input_chunk_copy, but returns a placeholder chunk 248MTMD_API mtmd_input_chunk * mtmd_input_chunk_get_placeholder (const mtmd_input_chunk * chunk ); 249 250// save/load an input chunk to/from a buffer (useful for KV save/load) 251// important: only chunk's metadata will be saved, the actual image/audio data will not be saved 252// the loaded chunk will always be a placeholder, cannot be used for mtmd_encode() or mtmd_batch_encode() 253// out_buf can be nullptr (to query expected_out_len) 254// returns 0 on success, non-zero on failure 255MTMD_API int32_t mtmd_input_chunk_save (const mtmd_input_chunk * chunk ,char * out_buf ,size_t out_len ,size_t * expected_out_len ); 256// returns nullptr on failure 257MTMD_API mtmd_input_chunk * mtmd_input_chunk_load (const char * buf ,size_t len ); 258 259 260// mtmd_image_tokens 261// 262// the instance will be constructed via mtmd_tokenize() 263// it will be freed along with mtmd_input_chunk 264MTMD_API size_t mtmd_image_tokens_get_n_tokens (const mtmd_image_tokens * image_tokens );// TODO: deprecate 265MTMD_API const char * mtmd_image_tokens_get_id (const mtmd_image_tokens * image_tokens );// TODO: deprecate 266// number of temporal positions (equals to max(t,h,w) for M-RoPE; equals to n_tokens otherwise) 267MTMD_API llama_pos mtmd_image_tokens_get_n_pos (const mtmd_image_tokens * image_tokens );// TODO: deprecate 268 269DEPRECATED (MTMD_API size_t mtmd_image_tokens_get_nx (const mtmd_image_tokens * image_tokens ), 270"use mtmd_image_tokens_get_decoder_pos() instead" ); 271DEPRECATED (MTMD_API size_t mtmd_image_tokens_get_ny (const mtmd_image_tokens * image_tokens ), 272"use mtmd_image_tokens_get_decoder_pos() instead" ); 273 274struct mtmd_decoder_pos { 275uint32_t t ; 276uint32_t x ; 277uint32_t y ; 278uint32_t z ;// unused for now, reserved for future use 279}; 280// get position for decoder attention, to be used by M-RoPE models 281// i is the index of the embedding token, ranging from 0 to mtmd_image_tokens_get_n_tokens() - 1 282// pos_0 is the absolute position of the first token 283// return relative position (for example, embedding 0 will have position (0, 0, 0); remember to adjust it to the current absolute position) 284MTMD_API struct mtmd_decoder_pos mtmd_image_tokens_get_decoder_pos (const mtmd_image_tokens * image_tokens ,llama_pos pos_0 ,size_t i ); 285 286// tokenize an input text prompt and a list of bitmaps (image/audio) 287// the prompt must have the input media marker (default: "<__media__>") in it 288// the default marker is defined by mtmd_default_marker() 289// the marker will be replaced with the media chunk 290// for example: 291// "here is an image: <__media__>\ndescribe it in detail." 292// this will gives 3 chunks: 293// 1. "here is an image: <start_of_image>" 294// 2. (image/audio tokens) 295// 3. "<end_of_image>\ndescribe it in detail." 296// number of bitmaps must be equal to the number of markers in the prompt 297// this function is thread-safe (shared ctx) 298// return values: 299// 0 on success 300// 1 on number of bitmaps not matching the number of markers 301// 2 on media preprocessing error 302MTMD_API int32_t mtmd_tokenize (const mtmd_context * ctx , 303mtmd_input_chunks * output , 304const mtmd_input_text * text , 305const mtmd_bitmap * const * bitmaps , 306size_t n_bitmaps ); 307 308// same as mtmd_tokenize(), but takes an array of mtmd_input_part 309// use cases: 310// - when you don't want to use media markers (they will be tokenized as normal text) 311// - when you want to control parse_special for each text part 312// note: per-part add_special will be ignored 313// return 1 if a part has both text and bitmap set (or neither) 314MTMD_API int32_t mtmd_tokenize_from_parts (const mtmd_context * ctx , 315mtmd_input_chunks * output , 316const mtmd_input_part * const * parts , 317size_t n_parts , 318bool add_special ); 319 320DEPRECATED (MTMD_API int32_t mtmd_encode (mtmd_context * ctx ,const mtmd_image_tokens * image_tokens ), 321"use mtmd_encode_chunk() instead" ); 322 323// text chunk will be ignored silently, only media chunk will be encoded 324// returns 0 on success 325// returns 1 on generic error 326MTMD_API int32_t mtmd_encode_chunk (mtmd_context * ctx , 327const mtmd_input_chunk * chunk ); 328 329// get output embeddings from the last encode pass 330// the reading size (in bytes) is equal to: 331// llama_model_n_embd_inp(model) * mtmd_input_chunk_get_n_tokens(chunk) * sizeof(float) 332MTMD_API float * mtmd_get_output_embd (mtmd_context * ctx ); 333 334 335// batch encoding API 336// chunks are not owned by the batch, they will not be freed by mtmd_batch_free() 337// batch is valid for a given context, cannot be shared across contexts 338MTMD_API mtmd_batch * mtmd_batch_init (mtmd_context * ctx ); 339MTMD_API void mtmd_batch_free (mtmd_batch * batch ); 340 341// only media chunks are allowed, text chunks will be rejected 342// returns 0 on success 343// returns 1 on generic error 344// returns 2 if the batch is too large (chunk won't be added) 345// returns 3 if it cannot be batched with the existing chunks in the batch 346MTMD_API int32_t mtmd_batch_add_chunk (mtmd_batch * batch ,const mtmd_input_chunk * chunk ); 347 348// returns 0 on success 349// returns 1 on generic error 350MTMD_API int32_t mtmd_batch_encode (mtmd_batch * batch ); 351MTMD_API float * mtmd_batch_get_output_embd (mtmd_batch * batch ,const mtmd_input_chunk * chunk ); 352 353 354// Set callback for all future logging events. 355// If this is not called, or NULL is supplied, everything is output on stderr. 356MTMD_API void mtmd_log_set (ggml_log_callback log_callback ,void * user_data ); 357 358// EXPERIMENTAL API to get mmproj's capabilities without initializing the full context 359// This is only intended to be used by llama-server, breaking changes is expected 360struct mtmd_caps { 361bool inp_vision ; 362bool inp_audio ; 363}; 364MTMD_API struct mtmd_caps mtmd_get_cap_from_file (const char * mmproj_fname ); 365 366///////////////////////////////////////// 367// EXPERIMENTAL API for audio generation, subjected to breaking changes 368 369// represent the pipeline type 370enum mtmd_gen_audio_type { 371MTMD_GEN_AUDIO_TYPE_NONE ,// not supported 372MTMD_GEN_AUDIO_TYPE_QWEN3TTS , 373MTMD_GEN_AUDIO_TYPE_POCKETTTS , 374}; 375 376struct mtmd_gen_audio_info { 377enum mtmd_gen_audio_type type ; 378int32_t sample_rate ;// in Hz, for example 24000 for qwen3tts 379const char * model_variant ;// name of the weight variant, can be nullptr if not applicable 380}; 381 382MTMD_API struct mtmd_gen_audio_info mtmd_gen_audio_get_info (const mtmd_context * ctx ); 383 384 385enum mtmd_gen_process_type { 386MTMD_GEN_PROCESS_TYPE_GEN_CODE ,// h_state to semantic (codes, mel-spectrogram, etc.) 387MTMD_GEN_PROCESS_TYPE_GEN_WAV ,// convert semantic to PCM audio 388// for qwen3tts, this is code2wav 389// for pocket-tts, this is mimi decoder 390}; 391 392struct mtmd_gen_inp { 393enum mtmd_gen_process_type type ; 394 395// for MTMD_GEN_PROCESS_TYPE_GEN_CODE 396int32_t code0 ;// the sampled codebook 0 entry from backbone 397float * embd ;// the hidden state from backbone, must have n_text_embd elements 398int32_t top_k ; 399float top_p ; 400uint32_t seed ;// UINT32_MAX for random 401float temp ;// sampling temperature, or noise scale for flow-matching decoders 402 403// for MTMD_GEN_PROCESS_TYPE_GEN_WAV 404// pass either codes (discrete) or feats (continuous), depending on the pipeline 405int32_t * codes ; 406size_t n_codes ; 407const float * feats ; 408size_t n_feats ; 409const char * state_data ; 410size_t state_size ; 411}; 412 413struct mtmd_gen_out { 414// note: output memory is allocated by the context, valid until next process() call 415 416// for MTMD_GEN_PROCESS_TYPE_GEN_CODE 417const int32_t * codes ; 418size_t n_codes ; 419const float * feats ;// continuous counterpart of codes 420size_t n_feats ; 421const float * embd ;// the generated hidden state, to be fed back to backbone 422// it must have n_text_embd elements 423bool is_eos ;// only set by pipelines having the EOS head inside mmproj 424 425// for MTMD_GEN_PROCESS_TYPE_GEN_WAV 426const float * audio ; 427size_t n_samples ; 428const char * state_data ; 429size_t state_size ; 430}; 431 432// defaults tuned for the loaded pipeline, callers override only what they care about 433MTMD_API struct mtmd_gen_inp mtmd_gen_inp_default (const mtmd_context * ctx ); 434 435// note: this API is stateless, caller must handle state management and audio frame accumulation 436MTMD_API int32_t mtmd_gen_audio_process (mtmd_context * ctx , 437const struct mtmd_gen_inp * inp , 438struct mtmd_gen_out * out ); 439 440///////////////////////////////////////// 441 442// test function, to be used in test-mtmd-c-api.c 443MTMD_API mtmd_input_chunks * mtmd_test_create_input_chunks (void ); 444 445#ifdef __cplusplus 446}// extern "C" 447#endif 448 449// Get memory usage of the current model in bytes, per backend device 450// Note: this is an unstable API, used internally by fit_params; it WILL be removed or changed without deprecation 451#ifdef __cplusplus 452MTMD_API std ::map < ggml_backend_dev_t ,size_t > mtmd_get_memory_usage ( 453const char * mmproj_fname , 454struct mtmd_context_params ctx_params ); 455#endif 456 457// 458// C++ wrappers 459// 460 461#ifdef __cplusplus 462 463namespace mtmd { 464 465struct mtmd_context_deleter { 466void operator ()(mtmd_context * val ) {mtmd_free (val ); } 467}; 468using context_ptr = std ::unique_ptr < mtmd_context ,mtmd_context_deleter > ; 469 470struct mtmd_bitmap_deleter { 471void operator ()(mtmd_bitmap * val ) {mtmd_bitmap_free (val ); } 472}; 473using bitmap_ptr = std ::unique_ptr < mtmd_bitmap ,mtmd_bitmap_deleter > ; 474 475struct mtmd_input_chunks_deleter { 476void operator ()(mtmd_input_chunks * val ) {mtmd_input_chunks_free (val ); } 477}; 478using input_chunks_ptr = std ::unique_ptr < mtmd_input_chunks ,mtmd_input_chunks_deleter > ; 479 480struct mtmd_input_chunk_deleter { 481void operator ()(mtmd_input_chunk * val ) {mtmd_input_chunk_free (val ); } 482}; 483using input_chunk_ptr = std ::unique_ptr < mtmd_input_chunk ,mtmd_input_chunk_deleter > ; 484 485struct mtmd_batch_deleter { 486void operator ()(mtmd_batch * val ) {mtmd_batch_free (val ); } 487}; 488using batch_ptr = std ::unique_ptr < mtmd_batch ,mtmd_batch_deleter > ; 489 490struct bitmap { 491bitmap_ptr ptr ; 492bitmap () :ptr (nullptr ) {} 493bitmap (mtmd_bitmap * bitmap ) :ptr (bitmap ) {} 494bitmap (bitmap && other )noexcept :ptr (std ::move (other .ptr )) {} 495bitmap (uint32_t nx ,uint32_t ny ,const unsigned char * data ) { 496ptr .reset (mtmd_bitmap_init (nx ,ny ,data )); 497 } 498 ~bitmap ()= default ; 499uint32_t nx ()const {return mtmd_bitmap_get_nx (ptr .get ()); } 500uint32_t ny ()const {return mtmd_bitmap_get_ny (ptr .get ()); } 501const unsigned char * data ()const {return mtmd_bitmap_get_data (ptr .get ()); } 502size_t n_bytes ()const {return mtmd_bitmap_get_n_bytes (ptr .get ()); } 503std ::string id ()const {return mtmd_bitmap_get_id (ptr .get ()); } 504void set_id (const char * id )const {mtmd_bitmap_set_id (ptr .get (),id ); } 505}; 506 507struct bitmaps { 508std ::vector < bitmap > entries ; 509 ~bitmaps ()= default ; 510// return list of pointers to mtmd_bitmap 511// example: 512// auto bitmaps_c_ptr = bitmaps.c_ptr(); 513// int32_t res = mtmd_tokenize(... bitmaps_c_ptr.data(), bitmaps_c_ptr.size()); 514std ::vector < const mtmd_bitmap *> c_ptr () { 515std ::vector < const mtmd_bitmap *> res (entries .size ()); 516for (size_t i = 0 ;i < entries .size ();i ++ ) { 517res [i ]= entries [i ].ptr .get (); 518 } 519return res ; 520 } 521}; 522 523struct input_chunks { 524input_chunks_ptr ptr ; 525input_chunks ()= default ; 526input_chunks (mtmd_input_chunks * chunks ) :ptr (chunks ) {} 527 ~input_chunks ()= default ; 528size_t size ()const {return mtmd_input_chunks_size (ptr .get ()); } 529const mtmd_input_chunk * operator [](size_t idx )const { 530return mtmd_input_chunks_get (ptr .get (),idx ); 531 } 532}; 533 534} // namespace mtmd 535 536#endif 537 538#endif