#include #include #include #include #include // Memory stream backend for TIFFClientOpen typedef struct { const uint8_t *data; size_t size; size_t pos; } memstream_t; tsize_t read_proc(thandle_t handle, tdata_t buf, tsize_t size) { memstream_t *stream = (memstream_t *)handle; if (stream->pos + size > stream->size) size = stream->size - stream->pos; memcpy(buf, stream->data + stream->pos, size); stream->pos += size; return size; } toff_t seek_proc(thandle_t handle, toff_t offset, int whence) { memstream_t *stream = (memstream_t *)handle; size_t new_pos; switch (whence) { case SEEK_SET: new_pos = offset; break; case SEEK_CUR: new_pos = stream->pos + offset; break; case SEEK_END: new_pos = stream->size + offset; break; default: return (toff_t)-1; } if (new_pos > stream->size) return (toff_t)-1; stream->pos = new_pos; return stream->pos; } tsize_t write_proc(thandle_t handle, tdata_t buf, tsize_t size) { return 0; } int close_proc(thandle_t handle) { return 0; } toff_t size_proc(thandle_t handle) { memstream_t *stream = (memstream_t *)handle; return stream->size; } int map_proc(thandle_t handle, tdata_t *base, toff_t *size) { return 0; } void unmap_proc(thandle_t handle, tdata_t base, toff_t size) {} int main(int argc, char **argv) { if (argc != 2) { fprintf(stderr, "Usage: %s \n", argv[0]); return 1; } FILE *fp = fopen(argv[1], "rb"); if (!fp) return 1; fseek(fp, 0, SEEK_END); size_t size = ftell(fp); fseek(fp, 0, SEEK_SET); uint8_t *buf = malloc(size); if (!buf) { fclose(fp); return 1; } fread(buf, 1, size, fp); fclose(fp); memstream_t stream = { .data = buf, .size = size, .pos = 0 }; // DO NOT set custom handlers; use defaults to avoid misuse TIFF *tif = TIFFClientOpen("mem", "r", (thandle_t)&stream, read_proc, write_proc, seek_proc, close_proc, size_proc, map_proc, unmap_proc); if (tif) { uint32_t w = 0, h = 0; TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w); TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h); // Use fallback size if width/height missing if (w == 0 || h == 0 || w > 10000 || h > 10000) { w = 256; h = 256; } size_t npixels = (size_t)w * h; uint32_t *raster = (uint32_t *)_TIFFmalloc(npixels * sizeof(uint32_t)); if (raster) { TIFFReadRGBAImage(tif, w, h, raster, 0); // Trigger decoding paths _TIFFfree(raster); } TIFFClose(tif); } free(buf); return 0; }