📄 tif_getimage.c
字号:
static int setorientation(TIFFRGBAImage* img){ switch (img->orientation) { case ORIENTATION_TOPLEFT: case ORIENTATION_LEFTTOP: if (img->req_orientation == ORIENTATION_TOPRIGHT || img->req_orientation == ORIENTATION_RIGHTTOP) return FLIP_HORIZONTALLY; else if (img->req_orientation == ORIENTATION_BOTRIGHT || img->req_orientation == ORIENTATION_RIGHTBOT) return FLIP_HORIZONTALLY | FLIP_VERTICALLY; else if (img->req_orientation == ORIENTATION_BOTLEFT || img->req_orientation == ORIENTATION_LEFTBOT) return FLIP_VERTICALLY; else return 0; case ORIENTATION_TOPRIGHT: case ORIENTATION_RIGHTTOP: if (img->req_orientation == ORIENTATION_TOPLEFT || img->req_orientation == ORIENTATION_LEFTTOP) return FLIP_HORIZONTALLY; else if (img->req_orientation == ORIENTATION_BOTRIGHT || img->req_orientation == ORIENTATION_RIGHTBOT) return FLIP_VERTICALLY; else if (img->req_orientation == ORIENTATION_BOTLEFT || img->req_orientation == ORIENTATION_LEFTBOT) return FLIP_HORIZONTALLY | FLIP_VERTICALLY; else return 0; case ORIENTATION_BOTRIGHT: case ORIENTATION_RIGHTBOT: if (img->req_orientation == ORIENTATION_TOPLEFT || img->req_orientation == ORIENTATION_LEFTTOP) return FLIP_HORIZONTALLY | FLIP_VERTICALLY; else if (img->req_orientation == ORIENTATION_TOPRIGHT || img->req_orientation == ORIENTATION_RIGHTTOP) return FLIP_VERTICALLY; else if (img->req_orientation == ORIENTATION_BOTLEFT || img->req_orientation == ORIENTATION_LEFTBOT) return FLIP_HORIZONTALLY; else return 0; case ORIENTATION_BOTLEFT: case ORIENTATION_LEFTBOT: if (img->req_orientation == ORIENTATION_TOPLEFT || img->req_orientation == ORIENTATION_LEFTTOP) return FLIP_VERTICALLY; else if (img->req_orientation == ORIENTATION_TOPRIGHT || img->req_orientation == ORIENTATION_RIGHTTOP) return FLIP_HORIZONTALLY | FLIP_VERTICALLY; else if (img->req_orientation == ORIENTATION_BOTRIGHT || img->req_orientation == ORIENTATION_RIGHTBOT) return FLIP_HORIZONTALLY; else return 0; default: /* NOTREACHED */ return 0; }}/* * Get an tile-organized image that has * PlanarConfiguration contiguous if SamplesPerPixel > 1 * or * SamplesPerPixel == 1 */ static intgtTileContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h){ TIFF* tif = img->tif; tileContigRoutine put = img->put.contig; uint32 col, row, y, rowstoread; uint32 pos; uint32 tw, th; unsigned char* buf; int32 fromskew, toskew; uint32 nrow; int ret = 1, flip; buf = (unsigned char*) _TIFFmalloc(TIFFTileSize(tif)); if (buf == 0) { TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for tile buffer"); return (0); } _TIFFmemset(buf, 0, TIFFTileSize(tif)); TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw); TIFFGetField(tif, TIFFTAG_TILELENGTH, &th); flip = setorientation(img); if (flip & FLIP_VERTICALLY) { y = h - 1; toskew = -(int32)(tw + w); } else { y = 0; toskew = -(int32)(tw - w); } for (row = 0; row < h; row += nrow) { rowstoread = th - (row + img->row_offset) % th; nrow = (row + rowstoread > h ? h - row : rowstoread); for (col = 0; col < w; col += tw) { if (TIFFReadTile(tif, buf, col+img->col_offset, row+img->row_offset, 0, 0) < 0 && img->stoponerr) { ret = 0; break; } pos = ((row+img->row_offset) % th) * TIFFTileRowSize(tif); if (col + tw > w) { /* * Tile is clipped horizontally. Calculate * visible portion and skewing factors. */ uint32 npix = w - col; fromskew = tw - npix; (*put)(img, raster+y*w+col, col, y, npix, nrow, fromskew, toskew + fromskew, buf + pos); } else { (*put)(img, raster+y*w+col, col, y, tw, nrow, 0, toskew, buf + pos); } } y += (flip & FLIP_VERTICALLY ? -(int32) nrow : (int32) nrow); } _TIFFfree(buf); if (flip & FLIP_HORIZONTALLY) { uint32 line; for (line = 0; line < h; line++) { uint32 *left = raster + (line * w); uint32 *right = left + w - 1; while ( left < right ) { uint32 temp = *left; *left = *right; *right = temp; left++, right--; } } } return (ret);}/* * Get an tile-organized image that has * SamplesPerPixel > 1 * PlanarConfiguration separated * We assume that all such images are RGB. */ static intgtTileSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h){ TIFF* tif = img->tif; tileSeparateRoutine put = img->put.separate; uint32 col, row, y, rowstoread; uint32 pos; uint32 tw, th; unsigned char* buf; unsigned char* r; unsigned char* g; unsigned char* b; unsigned char* a; tsize_t tilesize; int32 fromskew, toskew; int alpha = img->alpha; uint32 nrow; int ret = 1, flip; tilesize = TIFFTileSize(tif); buf = (unsigned char*) _TIFFmalloc(4*tilesize); if (buf == 0) { TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for tile buffer"); return (0); } _TIFFmemset(buf, 0, 4*tilesize); r = buf; g = r + tilesize; b = g + tilesize; a = b + tilesize; if (!alpha) _TIFFmemset(a, 0xff, tilesize); TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw); TIFFGetField(tif, TIFFTAG_TILELENGTH, &th); flip = setorientation(img); if (flip & FLIP_VERTICALLY) { y = h - 1; toskew = -(int32)(tw + w); } else { y = 0; toskew = -(int32)(tw - w); } for (row = 0; row < h; row += nrow) { rowstoread = th - (row + img->row_offset) % th; nrow = (row + rowstoread > h ? h - row : rowstoread); for (col = 0; col < w; col += tw) { if (TIFFReadTile(tif, r, col+img->col_offset, row+img->row_offset,0,0) < 0 && img->stoponerr) { ret = 0; break; } if (TIFFReadTile(tif, g, col+img->col_offset, row+img->row_offset,0,1) < 0 && img->stoponerr) { ret = 0; break; } if (TIFFReadTile(tif, b, col+img->col_offset, row+img->row_offset,0,2) < 0 && img->stoponerr) { ret = 0; break; } if (alpha && TIFFReadTile(tif,a,col+img->col_offset, row+img->row_offset,0,3) < 0 && img->stoponerr) { ret = 0; break; } pos = ((row+img->row_offset) % th) * TIFFTileRowSize(tif); if (col + tw > w) { /* * Tile is clipped horizontally. Calculate * visible portion and skewing factors. */ uint32 npix = w - col; fromskew = tw - npix; (*put)(img, raster+y*w+col, col, y, npix, nrow, fromskew, toskew + fromskew, r + pos, g + pos, b + pos, a + pos); } else { (*put)(img, raster+y*w+col, col, y, tw, nrow, 0, toskew, r + pos, g + pos, b + pos, a + pos); } } y += (flip & FLIP_VERTICALLY ?-(int32) nrow : (int32) nrow); } if (flip & FLIP_HORIZONTALLY) { uint32 line; for (line = 0; line < h; line++) { uint32 *left = raster + (line * w); uint32 *right = left + w - 1; while ( left < right ) { uint32 temp = *left; *left = *right; *right = temp; left++, right--; } } } _TIFFfree(buf); return (ret);}/* * Get a strip-organized image that has * PlanarConfiguration contiguous if SamplesPerPixel > 1 * or * SamplesPerPixel == 1 */ static intgtStripContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h){ TIFF* tif = img->tif; tileContigRoutine put = img->put.contig; uint32 row, y, nrow, rowstoread; uint32 pos; unsigned char* buf; uint32 rowsperstrip; uint32 imagewidth = img->width; tsize_t scanline; int32 fromskew, toskew; int ret = 1, flip; buf = (unsigned char*) _TIFFmalloc(TIFFStripSize(tif)); if (buf == 0) { TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for strip buffer"); return (0); } _TIFFmemset(buf, 0, TIFFStripSize(tif)); flip = setorientation(img); if (flip & FLIP_VERTICALLY) { y = h - 1; toskew = -(int32)(w + w); } else { y = 0; toskew = -(int32)(w - w); } TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); scanline = TIFFScanlineSize(tif); fromskew = (w < imagewidth ? imagewidth - w : 0); for (row = 0; row < h; row += nrow) { rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip; nrow = (row + rowstoread > h ? h - row : rowstoread); if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif,row+img->row_offset, 0), buf, ((row + img->row_offset)%rowsperstrip + nrow) * scanline) < 0 && img->stoponerr) { ret = 0; break; } pos = ((row + img->row_offset) % rowsperstrip) * scanline; (*put)(img, raster+y*w, 0, y, w, nrow, fromskew, toskew, buf + pos); y += (flip & FLIP_VERTICALLY ? -(int32) nrow : (int32) nrow); } if (flip & FLIP_HORIZONTALLY) { uint32 line; for (line = 0; line < h; line++) { uint32 *left = raster + (line * w); uint32 *right = left + w - 1; while ( left < right ) { uint32 temp = *left; *left = *right; *right = temp; left++, right--; } } } _TIFFfree(buf); return (ret);}/* * Get a strip-organized image with * SamplesPerPixel > 1 * PlanarConfiguration separated * We assume that all such images are RGB. */static intgtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h){ TIFF* tif = img->tif; tileSeparateRoutine put = img->put.separate; unsigned char *buf; unsigned char *r, *g, *b, *a; uint32 row, y, nrow, rowstoread; uint32 pos; tsize_t scanline; uint32 rowsperstrip, offset_row; uint32 imagewidth = img->width; tsize_t stripsize; int32 fromskew, toskew; int alpha = img->alpha; int ret = 1, flip; stripsize = TIFFStripSize(tif); r = buf = (unsigned char *)_TIFFmalloc(4*stripsize); if (buf == 0) { TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for tile buffer"); return (0); } _TIFFmemset(buf, 0, 4*stripsize); g = r + stripsize; b = g + stripsize; a = b + stripsize; if (!alpha) _TIFFmemset(a, 0xff, stripsize); flip = setorientation(img); if (flip & FLIP_VERTICALLY) { y = h - 1; toskew = -(int32)(w + w); } else { y = 0; toskew = -(int32)(w - w); } TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); scanline = TIFFScanlineSize(tif); fromskew = (w < imagewidth ? imagewidth - w : 0); for (row = 0; row < h; row += nrow) { rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip; nrow = (row + rowstoread > h ? h - row : rowstoread); offset_row = row + img->row_offset; if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 0), r, ((row + img->row_offset)%rowsperstrip + nrow) * scanline) < 0 && img->stoponerr) { ret = 0; break; } if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 1), g, ((row + img->row_offset)%rowsperstrip + nrow) * scanline) < 0 && img->stoponerr) { ret = 0; break; } if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 2), b, ((row + img->row_offset)%rowsperstrip + nrow) * scanline) < 0 && img->stoponerr) { ret = 0; break; } if (alpha && (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 3), a, ((row + img->row_offset)%rowsperstrip + nrow) * scanline) < 0 && img->stoponerr)) { ret = 0; break; } pos = ((row + img->row_offset) % rowsperstrip) * scanline; (*put)(img, raster+y*w, 0, y, w, nrow, fromskew, toskew, r + pos, g + pos, b + pos, a + pos); y += (flip & FLIP_VERTICALLY ? -(int32) nrow : (int32) nrow); } if (flip & FLIP_HORIZONTALLY) { uint32 line; for (line = 0; line < h; line++) { uint32 *left = raster + (line * w); uint32 *right = left + w - 1; while ( left < right ) { uint32 temp = *left; *left = *right; *right = temp; left++, right--; } } } _TIFFfree(buf); return (ret);}/* * The following routines move decoded data returned * from the TIFF library into rasters filled with packed * ABGR pixels (i.e. suitable for passing to lrecwrite.) * * The routines have been created according to the most * important cases and optimized. pickTileContigCase and * pickTileSeparateCase analyze the parameters and select * the appropriate "put" routine to use. */#define REPEAT8(op) REPEAT4(op); REPEAT4(op)#define REPEAT4(op) REPEAT2(op); REPEAT2(op)#define REPEAT2(op) op; op#define CASE8(x,op) \ switch (x) { \ case 7: op; case 6: op; case 5: op; \ case 4: op; case 3: op; case 2: op; \ case 1: op; \ }#define CASE4(x,op) switch (x) { case 3: op; case 2: op; case 1: op; }#define NOP#define UNROLL8(w, op1, op2) { \ uint32 _x; \ for (_x = w; _x >= 8; _x -= 8) { \ op1; \ REPEAT8(op2); \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -