From 1fdd74dc327d3842b6b448db6356e5b3d30f30e1 Mon Sep 17 00:00:00 2001 From: along Date: Fri, 11 Jul 2025 19:42:03 +0800 Subject: [PATCH] =?UTF-8?q?libtiff=E8=A7=A3=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/io_uring_tile.c | 112 +++++++++++++++++++++++++++++++++ src/parse_tiff.c | 87 +++++++++++++++++++++++++ tile_info.c => src/tile_info.c | 0 tile_info | Bin 16200 -> 0 bytes 4 files changed, 199 insertions(+) create mode 100644 src/io_uring_tile.c create mode 100644 src/parse_tiff.c rename tile_info.c => src/tile_info.c (100%) delete mode 100755 tile_info diff --git a/src/io_uring_tile.c b/src/io_uring_tile.c new file mode 100644 index 0000000..8c19c4d --- /dev/null +++ b/src/io_uring_tile.c @@ -0,0 +1,112 @@ +#include +#include +#include +#include +#include +#include + +#define MAX_TILES 1024 + +int main() +{ + // 打开 TIFF 文件 + int fd = open("imgs/ortho.tif", O_RDONLY); + if (fd < 0) + { + perror("open"); + return 1; + } + + TIFF *tif = TIFFOpen("imgs/ortho.tif", "r"); + if (!tif) + { + printf("Failed to open TIFF.\n"); + close(fd); + return 1; + } + + uint32 tileWidth, tileHeight; + TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tileWidth); + TIFFGetField(tif, TIFFTAG_TILELENGTH, &tileHeight); + + uint32 imageWidth, imageHeight; + TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &imageWidth); + TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &imageHeight); + + uint32 tilesAcross = (imageWidth + tileWidth - 1) / tileWidth; + uint32 tilesDown = (imageHeight + tileHeight - 1) / tileHeight; + uint32 totalTiles = tilesAcross * tilesDown; + if (totalTiles > MAX_TILES) + { + printf("Too many tiles (> %d)\n", MAX_TILES); + TIFFClose(tif); + close(fd); + return 1; + } + + tsize_t *byteCounts = NULL; + toff_t *offsets = NULL; + + TIFFGetField(tif, TIFFTAG_TILEBYTECOUNTS, &byteCounts); + TIFFGetField(tif, TIFFTAG_TILEOFFSETS, &offsets); + + // 初始化 io_uring + struct io_uring ring; + io_uring_queue_init(totalTiles, &ring, 0); + + // 分配 buffer 指针数组 + char *buffers[MAX_TILES]; + + // 提交异步读请求 + for (uint32 i = 0; i < totalTiles; i++) + { + buffers[i] = malloc(byteCounts[i]); + if (!buffers[i]) + { + perror("malloc"); + // 应该加清理,略 + break; + } + + struct io_uring_sqe *sqe = io_uring_get_sqe(&ring); + io_uring_prep_read(sqe, fd, buffers[i], byteCounts[i], offsets[i]); + io_uring_sqe_set_data(sqe, buffers[i]); + } + + io_uring_submit(&ring); + + // 等待所有完成 + for (uint32 i = 0; i < totalTiles; i++) + { + struct io_uring_cqe *cqe; + int ret = io_uring_wait_cqe(&ring, &cqe); + if (ret < 0) + { + fprintf(stderr, "io_uring_wait_cqe error: %d\n", ret); + // 处理错误,略 + } + if (cqe->res < 0) + { + fprintf(stderr, "Async read failed: %d\n", cqe->res); + } + else + { + // 成功读到 cqe->res 字节数据 + char *data = io_uring_cqe_get_data(cqe); + // 这里 data 指向对应 tile 的缓冲区 + // 你可以对 data 进一步解码处理 + } + io_uring_cqe_seen(&ring, cqe); + } + + // 清理 + for (uint32 i = 0; i < totalTiles; i++) + { + free(buffers[i]); + } + io_uring_queue_exit(&ring); + TIFFClose(tif); + close(fd); + + return 0; +} diff --git a/src/parse_tiff.c b/src/parse_tiff.c new file mode 100644 index 0000000..7bb0828 --- /dev/null +++ b/src/parse_tiff.c @@ -0,0 +1,87 @@ +#include +#include +#include + +int main() +{ + TIFF *tif = TIFFOpen("imgs/ortho.tif", "r"); + if (!tif) + { + printf("Failed to open file.\n"); + return 1; + } + + uint32 tileWidth, tileHeight; + TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tileWidth); + TIFFGetField(tif, TIFFTAG_TILELENGTH, &tileHeight); + printf("Tile size: %dx%d\n", tileWidth, tileHeight); + + uint32 imageWidth, imageHeight; + TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &imageWidth); + TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &imageHeight); + + uint32 tilesAcross = (imageWidth + tileWidth - 1) / tileWidth; + uint32 tilesDown = (imageHeight + tileHeight - 1) / tileHeight; + uint32 totalTiles = tilesAcross * tilesDown; + printf("Tile count: %d x %d = %d\n", tilesAcross, tilesDown, totalTiles); + + uint16 samplesPerPixel; + uint16 bitsPerSample; + + TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesPerPixel); + TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bitsPerSample); + + printf("Samples per pixel: %d\n", samplesPerPixel); + printf("Bits per sample: %d\n", bitsPerSample); + + uint16 sampleFormat = SAMPLEFORMAT_UINT; + TIFFGetField(tif, TIFFTAG_SAMPLEFORMAT, &sampleFormat); + printf("Sample format: %d\n", sampleFormat); // 1=uint, 2=int, 3=float + + tsize_t tileBufSize = TIFFTileSize(tif); + if (tileBufSize == 0) + { + printf("TIFFTileSize returned 0. Possibly not tiled.\n"); + TIFFClose(tif); + return 1; + } + + // 分配一个缓冲区用于存放一个 tile 的像素数据(未压缩) + uint8_t *tileBuf = (uint8_t *)_TIFFmalloc(tileBufSize); + if (!tileBuf) + { + fprintf(stderr, "Failed to allocate tile buffer.\n"); + TIFFClose(tif); + return 1; + } + + // 遍历每个 tile 并解码为像素数据 + for (uint32 i = 0; i < totalTiles; i++) + { + // 读取 tile 编号 i,解码为原始像素,存入 tileBuf + tsize_t readBytes = TIFFReadEncodedTile(tif, i, tileBuf, tileBufSize); + if (readBytes == -1) + { + fprintf(stderr, "Failed to decode tile %d\n", i); + continue; + } + + printf("Tile %3d: Decoded %6ld bytes (uncompressed pixel data)\n", + i, (long)readBytes); + + // 示例:打印前4个像素(假设每像素 samplesPerPixel 个 uint8 通道) + for (int px = 0; px < 4 && px < (readBytes / samplesPerPixel); px++) + { + printf(" Pixel %d: ", px); + for (int s = 0; s < samplesPerPixel; s++) + { + printf("%3u ", tileBuf[px * samplesPerPixel + s]); + } + printf("\n"); + } + } + + _TIFFfree(tileBuf); + TIFFClose(tif); + return 0; +} diff --git a/tile_info.c b/src/tile_info.c similarity index 100% rename from tile_info.c rename to src/tile_info.c diff --git a/tile_info b/tile_info deleted file mode 100755 index 9a40ab0ceb4c34600775b50b2a0f494bda802d0f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16200 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