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 9a40ab0..0000000 Binary files a/tile_info and /dev/null differ