⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tif_getimage.c

📁 一个国人自己实现图像库的程序(有参考价值)
💻 C
📖 第 1 页 / 共 5 页
字号:
    img->BWmap = (uint32**) _TIFFmalloc(	256*sizeof (uint32 *)+(256*nsamples*sizeof(uint32)));    if (img->BWmap == NULL) {	TIFFError(TIFFFileName(img->tif), "No space for B&W mapping table");	return (0);    }    p = (uint32*)(img->BWmap + 256);    for (i = 0; i < 256; i++) {	TIFFRGBValue c;	img->BWmap[i] = p;	switch (bitspersample) {#define	GREY(x)	c = Map[x]; *p++ = PACK(c,c,c);	case 1:	    GREY(i>>7);	    GREY((i>>6)&1);	    GREY((i>>5)&1);	    GREY((i>>4)&1);	    GREY((i>>3)&1);	    GREY((i>>2)&1);	    GREY((i>>1)&1);	    GREY(i&1);	    break;	case 2:	    GREY(i>>6);	    GREY((i>>4)&3);	    GREY((i>>2)&3);	    GREY(i&3);	    break;	case 4:	    GREY(i>>4);	    GREY(i&0xf);	    break;	case 8:        case 16:	    GREY(i);	    break;	}#undef	GREY    }    return (1);}/* * Construct a mapping table to convert from the range * of the data samples to [0,255] --for display.  This * process also handles inverting B&W images when needed. */ static intsetupMap(TIFFRGBAImage* img){    int32 x, range;    range = (int32)((1L<<img->bitspersample)-1);        /* treat 16 bit the same as eight bit */    if( img->bitspersample == 16 )        range = (int32) 255;    img->Map = (TIFFRGBValue*) _TIFFmalloc((range+1) * sizeof (TIFFRGBValue));    if (img->Map == NULL) {	TIFFError(TIFFFileName(img->tif),	    "No space for photometric conversion table");	return (0);    }    if (img->photometric == PHOTOMETRIC_MINISWHITE) {	for (x = 0; x <= range; x++)	    img->Map[x] = (TIFFRGBValue) (((range - x) * 255) / range);    } else {	for (x = 0; x <= range; x++)	    img->Map[x] = (TIFFRGBValue) ((x * 255) / range);    }    if (img->bitspersample <= 16 &&	(img->photometric == PHOTOMETRIC_MINISBLACK ||	 img->photometric == PHOTOMETRIC_MINISWHITE)) {	/*	 * Use photometric mapping table to construct	 * unpacking tables for samples <= 8 bits.	 */	if (!makebwmap(img))	    return (0);	/* no longer need Map, free it */	_TIFFfree(img->Map), img->Map = NULL;    }    return (1);}static intcheckcmap(TIFFRGBAImage* img){    uint16* r = img->redcmap;    uint16* g = img->greencmap;    uint16* b = img->bluecmap;    long n = 1L<<img->bitspersample;    while (n-- > 0)	if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256)	    return (16);    return (8);}static voidcvtcmap(TIFFRGBAImage* img){    uint16* r = img->redcmap;    uint16* g = img->greencmap;    uint16* b = img->bluecmap;    long i;    for (i = (1L<<img->bitspersample)-1; i >= 0; i--) {#define	CVT(x)		((uint16)((x)>>8))	r[i] = CVT(r[i]);	g[i] = CVT(g[i]);	b[i] = CVT(b[i]);#undef	CVT    }}/* * Palette images with <= 8 bits/sample are handled * with a table to avoid lots of shifts and masks.  The table * is setup so that put*cmaptile (below) can retrieve 8/bitspersample * pixel values simply by indexing into the table with one * number. */static intmakecmap(TIFFRGBAImage* img){    int bitspersample = img->bitspersample;    int nsamples = 8 / bitspersample;    uint16* r = img->redcmap;    uint16* g = img->greencmap;    uint16* b = img->bluecmap;    uint32 *p;    int i;    img->PALmap = (uint32**) _TIFFmalloc(	256*sizeof (uint32 *)+(256*nsamples*sizeof(uint32)));    if (img->PALmap == NULL) {	TIFFError(TIFFFileName(img->tif), "No space for Palette mapping table");	return (0);    }    p = (uint32*)(img->PALmap + 256);    for (i = 0; i < 256; i++) {	TIFFRGBValue c;	img->PALmap[i] = p;#define	CMAP(x)	c = x; *p++ = PACK(r[c]&0xff, g[c]&0xff, b[c]&0xff);	switch (bitspersample) {	case 1:	    CMAP(i>>7);	    CMAP((i>>6)&1);	    CMAP((i>>5)&1);	    CMAP((i>>4)&1);	    CMAP((i>>3)&1);	    CMAP((i>>2)&1);	    CMAP((i>>1)&1);	    CMAP(i&1);	    break;	case 2:	    CMAP(i>>6);	    CMAP((i>>4)&3);	    CMAP((i>>2)&3);	    CMAP(i&3);	    break;	case 4:	    CMAP(i>>4);	    CMAP(i&0xf);	    break;	case 8:	    CMAP(i);	    break;	}#undef CMAP    }    return (1);}/*  * Construct any mapping table used * by the associated put routine. */static intbuildMap(TIFFRGBAImage* img){    switch (img->photometric) {    case PHOTOMETRIC_RGB:    case PHOTOMETRIC_YCBCR:    case PHOTOMETRIC_SEPARATED:	if (img->bitspersample == 8)	    break;	/* fall thru... */    case PHOTOMETRIC_MINISBLACK:    case PHOTOMETRIC_MINISWHITE:	if (!setupMap(img))	    return (0);	break;    case PHOTOMETRIC_PALETTE:	/*	 * Convert 16-bit colormap to 8-bit (unless it looks	 * like an old-style 8-bit colormap).	 */	if (checkcmap(img) == 16)	    cvtcmap(img);	else	    TIFFWarning(TIFFFileName(img->tif), "Assuming 8-bit colormap");	/*	 * Use mapping table and colormap to construct	 * unpacking tables for samples < 8 bits.	 */	if (img->bitspersample <= 8 && !makecmap(img))	    return (0);	break;    }    return (1);}/* * Select the appropriate conversion routine for packed data. */static intpickTileContigCase(TIFFRGBAImage* img){    tileContigRoutine put = 0;    if (buildMap(img)) {	switch (img->photometric) {	case PHOTOMETRIC_RGB:	    switch (img->bitspersample) {	    case 8:		if (!img->Map) {		    if (img->alpha == EXTRASAMPLE_ASSOCALPHA)			put = putRGBAAcontig8bittile;		    else if (img->alpha == EXTRASAMPLE_UNASSALPHA)			put = putRGBUAcontig8bittile;		    else			put = putRGBcontig8bittile;		} else		    put = putRGBcontig8bitMaptile;		break;	    case 16:		put = putRGBcontig16bittile;		if (!img->Map) {		    if (img->alpha == EXTRASAMPLE_ASSOCALPHA)			put = putRGBAAcontig16bittile;		    else if (img->alpha == EXTRASAMPLE_UNASSALPHA)			put = putRGBUAcontig16bittile;		}		break;	    }	    break;	case PHOTOMETRIC_SEPARATED:	    if (img->bitspersample == 8) {		if (!img->Map)		    put = putRGBcontig8bitCMYKtile;		else		    put = putRGBcontig8bitCMYKMaptile;	    }	    break;	case PHOTOMETRIC_PALETTE:	    switch (img->bitspersample) {	    case 8:	put = put8bitcmaptile; break;	    case 4: put = put4bitcmaptile; break;	    case 2: put = put2bitcmaptile; break;	    case 1: put = put1bitcmaptile; break;	    }	    break;	case PHOTOMETRIC_MINISWHITE:	case PHOTOMETRIC_MINISBLACK:	    switch (img->bitspersample) {            case 16: put = put16bitbwtile; break;	    case 8:  put = putgreytile; break;	    case 4:  put = put4bitbwtile; break;	    case 2:  put = put2bitbwtile; break;	    case 1:  put = put1bitbwtile; break;	    }	    break;	case PHOTOMETRIC_YCBCR:	    if (img->bitspersample == 8)		put = initYCbCrConversion(img);	    break;	}    }    return ((img->put.contig = put) != 0);}/* * Select the appropriate conversion routine for unpacked data. * * NB: we assume that unpacked single channel data is directed *	 to the "packed routines. */static intpickTileSeparateCase(TIFFRGBAImage* img){    tileSeparateRoutine put = 0;    if (buildMap(img)) {	switch (img->photometric) {	case PHOTOMETRIC_RGB:	    switch (img->bitspersample) {	    case 8:		if (!img->Map) {		    if (img->alpha == EXTRASAMPLE_ASSOCALPHA)			put = putRGBAAseparate8bittile;		    else if (img->alpha == EXTRASAMPLE_UNASSALPHA)			put = putRGBUAseparate8bittile;		    else			put = putRGBseparate8bittile;		} else		    put = putRGBseparate8bitMaptile;		break;	    case 16:		put = putRGBseparate16bittile;		if (!img->Map) {		    if (img->alpha == EXTRASAMPLE_ASSOCALPHA)			put = putRGBAAseparate16bittile;		    else if (img->alpha == EXTRASAMPLE_UNASSALPHA)			put = putRGBUAseparate16bittile;		}		break;	    }	    break;	}    }    return ((img->put.separate = put) != 0);}/* * Read a whole strip off data from the file, and convert to RGBA form. * If this is the last strip, then it will only contain the portion of * the strip that is actually within the image space.  The result is * organized in bottom to top form. */intTIFFReadRGBAStrip(TIFF* tif, uint32 row, uint32 * raster ){    char 	emsg[1024];    TIFFRGBAImage img;    int 	ok;    uint32	rowsperstrip, rows_to_read;    if( TIFFIsTiled( tif ) )    {        TIFFError(TIFFFileName(tif),                  "Can't use TIFFReadRGBAStrip() with tiled file.");	return (0);    }        TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);    if( (row % rowsperstrip) != 0 )    {        TIFFError(TIFFFileName(tif),                "Row passed to TIFFReadRGBAStrip() must be first in a strip.");	return (0);    }    if (TIFFRGBAImageBegin(&img, tif, 0, emsg)) {        img.row_offset = row;        img.col_offset = 0;        if( row + rowsperstrip > img.height )            rows_to_read = img.height - row;        else            rows_to_read = rowsperstrip;        	ok = TIFFRGBAImageGet(&img, raster, img.width, rows_to_read );        	TIFFRGBAImageEnd(&img);    } else {	TIFFError(TIFFFileName(tif), emsg);	ok = 0;    }        return (ok);}/* * Read a whole tile off data from the file, and convert to RGBA form. * The returned RGBA data is organized from bottom to top of tile, * and may include zeroed areas if the tile extends off the image. */intTIFFReadRGBATile(TIFF* tif, uint32 col, uint32 row, uint32 * raster){    char 	emsg[1024];    TIFFRGBAImage img;    int 	ok;    uint32	tile_xsize, tile_ysize;    uint32	read_xsize, read_ysize;    uint32	i_row;    /*     * Verify that our request is legal - on a tile file, and on a     * tile boundary.     */        if( !TIFFIsTiled( tif ) )    {        TIFFError(TIFFFileName(tif),                  "Can't use TIFFReadRGBATile() with stripped file.");	return (0);    }        TIFFGetFieldDefaulted(tif, TIFFTAG_TILEWIDTH, &tile_xsize);    TIFFGetFieldDefaulted(tif, TIFFTAG_TILELENGTH, &tile_ysize);    if( (col % tile_xsize) != 0 || (row % tile_ysize) != 0 )    {        TIFFError(TIFFFileName(tif),                  "Row/col passed to TIFFReadRGBATile() must be top"                  "left corner of a tile.");	return (0);    }    /*     * Setup the RGBA reader.     */        if ( !TIFFRGBAImageBegin(&img, tif, 0, emsg)) {	TIFFError(TIFFFileName(tif), emsg);        return( 0 );    }    /*     * The TIFFRGBAImageGet() function doesn't allow us to get off the     * edge of the image, even to fill an otherwise valid tile.  So we     * figure out how much we can read, and fix up the tile buffer to     * a full tile configuration afterwards.     */    if( row + tile_ysize > img.height )        read_ysize = img.height - row;    else        read_ysize = tile_ysize;        if( col + tile_xsize > img.width )        read_xsize = img.width - col;    else        read_xsize = tile_xsize;    /*     * Read the chunk of imagery.     */        img.row_offset = row;    img.col_offset = col;    ok = TIFFRGBAImageGet(&img, raster, read_xsize, read_ysize );            TIFFRGBAImageEnd(&img);    /*     * If our read was incomplete we will need to fix up the tile by     * shifting the data around as if a full tile of data is being returned.     *     * This is all the more complicated because the image is organized in     * bottom to top format.      */    if( read_xsize == tile_xsize && read_ysize == tile_ysize )        return( ok );    for( i_row = 0; i_row < read_ysize; i_row++ )    {        memmove( raster + (tile_ysize - i_row - 1) * tile_xsize,                 raster + (read_ysize - i_row - 1) * read_xsize,                 read_xsize * sizeof(uint32) );        _TIFFmemset( raster + (tile_ysize - i_row - 1) * tile_xsize+read_xsize,                     0, sizeof(uint32) * (tile_xsize - read_xsize) );    }    for( i_row = read_ysize; i_row < tile_ysize; i_row++ )    {        _TIFFmemset( raster + (tile_ysize - i_row - 1) * tile_xsize,                     0, sizeof(uint32) * tile_xsize );    }    return (ok);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -