diff --git a/tools/mtmd/mtmd-image.cpp b/tools/mtmd/mtmd-image.cpp index e795b47e06..fac55ef8e3 100644 --- a/tools/mtmd/mtmd-image.cpp +++ b/tools/mtmd/mtmd-image.cpp @@ -1606,12 +1606,19 @@ mtmd_image_preproc_out mtmd_image_preprocessor_granite::preprocess(const clip_im const clip_image_size orig_size = img.get_size(); const int tile_size = hparams.image_size; + GGML_ASSERT(tile_size > 0); // llava-next always encodes an overview plus a grid of tiles, even for small images const clip_image_size refined_size = select_best_resolution(orig_size, hparams.image_res_candidates); const int grid_x = refined_size.width / tile_size; const int grid_y = refined_size.height / tile_size; + // the stacked image is tile_size * (1 + grid_x*grid_y) tall, it must fit in an int + const int64_t stacked_h = (int64_t) tile_size * (1 + (int64_t) grid_x * grid_y); + if (grid_x < 0 || grid_y < 0 || stacked_h > std::numeric_limits::max()) { + throw std::runtime_error("invalid image grid, check image_grid_pinpoints in the mmproj file"); + } + clip_image_u8 overview; img_tool::resize(img, overview, {tile_size, tile_size}, hparams.image_resize_algo_ov, hparams.image_pad_ov, hparams.image_pad_color_ov);