libtiff解析
This commit is contained in:
parent
237c4d8c47
commit
1fdd74dc32
112
src/io_uring_tile.c
Normal file
112
src/io_uring_tile.c
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <liburing.h>
|
||||||
|
#include <tiffio.h>
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
87
src/parse_tiff.c
Normal file
87
src/parse_tiff.c
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <tiffio.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user