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

📄 tif_getimage.c

📁 一个国人自己实现图像库的程序(有参考价值)
💻 C
📖 第 1 页 / 共 5 页
字号:
/* $Header: /cvsroot/osrs/libtiff/libtiff/tif_getimage.c,v 1.15 2001/09/24 19:40:37 warmerda Exp $ *//* * Copyright (c) 1991-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * * Permission to use, copy, modify, distribute, and sell this software and  * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. *  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.   *  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE  * OF THIS SOFTWARE. *//* * TIFF Library * * Read and return a packed RGBA image. */
#pragma warning (disable : 4550)

#include "tiffiop.h"#include <assert.h>#include <stdio.h>static	int gtTileContig(TIFFRGBAImage*, uint32*, uint32, uint32);static	int gtTileSeparate(TIFFRGBAImage*, uint32*, uint32, uint32);static	int gtStripContig(TIFFRGBAImage*, uint32*, uint32, uint32);static	int gtStripSeparate(TIFFRGBAImage*, uint32*, uint32, uint32);static	int pickTileContigCase(TIFFRGBAImage*);static	int pickTileSeparateCase(TIFFRGBAImage*);static	const char photoTag[] = "PhotometricInterpretation";/* * Check the image to see if TIFFReadRGBAImage can deal with it. * 1/0 is returned according to whether or not the image can * be handled.  If 0 is returned, emsg contains the reason * why it is being rejected. */intTIFFRGBAImageOK(TIFF* tif, char emsg[1024]){    TIFFDirectory* td = &tif->tif_dir;    uint16 photometric;    int colorchannels;    switch (td->td_bitspersample) {    case 1: case 2: case 4:    case 8: case 16:	break;    default:	sprintf(emsg, "Sorry, can not handle images with %d-bit samples",	    td->td_bitspersample);	return (0);    }    colorchannels = td->td_samplesperpixel - td->td_extrasamples;    if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric)) {	switch (colorchannels) {	case 1:	    photometric = PHOTOMETRIC_MINISBLACK;	    break;	case 3:	    photometric = PHOTOMETRIC_RGB;	    break;	default:	    sprintf(emsg, "Missing needed %s tag", photoTag);	    return (0);	}    }    switch (photometric) {    case PHOTOMETRIC_MINISWHITE:    case PHOTOMETRIC_MINISBLACK:    case PHOTOMETRIC_PALETTE:	if (td->td_planarconfig == PLANARCONFIG_CONTIG             && td->td_samplesperpixel != 1            && td->td_bitspersample < 8 ) {	    sprintf(emsg,                    "Sorry, can not handle contiguous data with %s=%d, "                    "and %s=%d and Bits/Sample=%d",                    photoTag, photometric,                    "Samples/pixel", td->td_samplesperpixel,                    td->td_bitspersample);	    return (0);	}        /*        ** We should likely validate that any extra samples are either        ** to be ignored, or are alpha, and if alpha we should try to use        ** them.  But for now we won't bother with this.         */	break;    case PHOTOMETRIC_YCBCR:	if (td->td_planarconfig != PLANARCONFIG_CONTIG) {	    sprintf(emsg, "Sorry, can not handle YCbCr images with %s=%d",		"Planarconfiguration", td->td_planarconfig);	    return (0);	}	break;    case PHOTOMETRIC_RGB: 	if (colorchannels < 3) {	    sprintf(emsg, "Sorry, can not handle RGB image with %s=%d",		"Color channels", colorchannels);	    return (0);	}	break;#ifdef CMYK_SUPPORT    case PHOTOMETRIC_SEPARATED:	if (td->td_inkset != INKSET_CMYK) {	    sprintf(emsg, "Sorry, can not handle separated image with %s=%d",		"InkSet", td->td_inkset);	    return (0);	}	if (td->td_samplesperpixel < 4) {	    sprintf(emsg, "Sorry, can not handle separated image with %s=%d",		"Samples/pixel", td->td_samplesperpixel);	    return (0);	}	break;#endif    case PHOTOMETRIC_LOGL:	if (td->td_compression != COMPRESSION_SGILOG) {	    sprintf(emsg, "Sorry, LogL data must have %s=%d",		"Compression", COMPRESSION_SGILOG);	    return (0);	}	break;    case PHOTOMETRIC_LOGLUV:	if (td->td_compression != COMPRESSION_SGILOG &&		td->td_compression != COMPRESSION_SGILOG24) {	    sprintf(emsg, "Sorry, LogLuv data must have %s=%d or %d",		"Compression", COMPRESSION_SGILOG, COMPRESSION_SGILOG24);	    return (0);	}	if (td->td_planarconfig != PLANARCONFIG_CONTIG) {	    sprintf(emsg, "Sorry, can not handle LogLuv images with %s=%d",		"Planarconfiguration", td->td_planarconfig);	    return (0);	}	break;    default:	sprintf(emsg, "Sorry, can not handle image with %s=%d",	    photoTag, photometric);	return (0);    }    return (1);}voidTIFFRGBAImageEnd(TIFFRGBAImage* img){    if (img->Map)	_TIFFfree(img->Map), img->Map = NULL;    if (img->BWmap)	_TIFFfree(img->BWmap), img->BWmap = NULL;    if (img->PALmap)	_TIFFfree(img->PALmap), img->PALmap = NULL;    if (img->ycbcr)	_TIFFfree(img->ycbcr), img->ycbcr = NULL;    if( img->redcmap ) {        _TIFFfree( img->redcmap );        _TIFFfree( img->greencmap );        _TIFFfree( img->bluecmap );    }}static intisCCITTCompression(TIFF* tif){    uint16 compress;    TIFFGetField(tif, TIFFTAG_COMPRESSION, &compress);    return (compress == COMPRESSION_CCITTFAX3 ||	    compress == COMPRESSION_CCITTFAX4 ||	    compress == COMPRESSION_CCITTRLE ||	    compress == COMPRESSION_CCITTRLEW);}intTIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stop, char emsg[1024]){    uint16* sampleinfo;    uint16 extrasamples;    uint16 planarconfig;    uint16 compress;    int colorchannels;    uint16	*red_orig, *green_orig, *blue_orig;    int		n_color;    /* Initialize to normal values */    img->row_offset = 0;    img->col_offset = 0;    img->redcmap = NULL;    img->greencmap = NULL;    img->bluecmap = NULL;        img->tif = tif;    img->stoponerr = stop;    TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &img->bitspersample);    switch (img->bitspersample) {    case 1: case 2: case 4:    case 8: case 16:	break;    default:	sprintf(emsg, "Sorry, can not image with %d-bit samples",	    img->bitspersample);	return (0);    }    img->alpha = 1;    TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &img->samplesperpixel);    TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES,	&extrasamples, &sampleinfo);    if (extrasamples == 1)	switch (sampleinfo[0]) {	case EXTRASAMPLE_ASSOCALPHA:	/* data is pre-multiplied */	case EXTRASAMPLE_UNASSALPHA:	/* data is not pre-multiplied */	    img->alpha = sampleinfo[0];	    break;	}    colorchannels = img->samplesperpixel - extrasamples;    TIFFGetFieldDefaulted(tif, TIFFTAG_COMPRESSION, &compress);    TIFFGetFieldDefaulted(tif, TIFFTAG_PLANARCONFIG, &planarconfig);    if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &img->photometric)) {	switch (colorchannels) {	case 1:	    if (isCCITTCompression(tif))		img->photometric = PHOTOMETRIC_MINISWHITE;	    else		img->photometric = PHOTOMETRIC_MINISBLACK;	    break;	case 3:	    img->photometric = PHOTOMETRIC_RGB;	    break;	default:	    sprintf(emsg, "Missing needed %s tag", photoTag);	    return (0);	}    }    switch (img->photometric) {    case PHOTOMETRIC_PALETTE:	if (!TIFFGetField(tif, TIFFTAG_COLORMAP,	    &red_orig, &green_orig, &blue_orig)) {	    TIFFError(TIFFFileName(tif), "Missing required \"Colormap\" tag");	    return (0);	}        /* copy the colormaps so we can modify them */        n_color = (1L << img->bitspersample);        img->redcmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color);        img->greencmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color);        img->bluecmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color);        if( !img->redcmap || !img->greencmap || !img->bluecmap ) {	    TIFFError(TIFFFileName(tif), "Out of memory for colormap copy");	    return (0);        }        memcpy( img->redcmap, red_orig, n_color * 2 );        memcpy( img->greencmap, green_orig, n_color * 2 );        memcpy( img->bluecmap, blue_orig, n_color * 2 );        	/* fall thru... */    case PHOTOMETRIC_MINISWHITE:    case PHOTOMETRIC_MINISBLACK:	if (planarconfig == PLANARCONFIG_CONTIG             && img->samplesperpixel != 1            && img->bitspersample < 8 ) {	    sprintf(emsg,                    "Sorry, can not handle contiguous data with %s=%d, "                    "and %s=%d and Bits/Sample=%d",                    photoTag, img->photometric,                    "Samples/pixel", img->samplesperpixel,                    img->bitspersample);	    return (0);	}	break;    case PHOTOMETRIC_YCBCR:	if (planarconfig != PLANARCONFIG_CONTIG) {	    sprintf(emsg, "Sorry, can not handle YCbCr images with %s=%d",		"Planarconfiguration", planarconfig);	    return (0);	}	/* It would probably be nice to have a reality check here. */	if (planarconfig == PLANARCONFIG_CONTIG)	    /* can rely on libjpeg to convert to RGB */	    /* XXX should restore current state on exit */	    switch (compress) {		case COMPRESSION_OJPEG:		case COMPRESSION_JPEG:		    TIFFSetField(tif, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);		    img->photometric = PHOTOMETRIC_RGB;                    break;                default:                    /* do nothing */;                    break;	    }	break;    case PHOTOMETRIC_RGB: 	if (colorchannels < 3) {	    sprintf(emsg, "Sorry, can not handle RGB image with %s=%d",		"Color channels", colorchannels);	    return (0);	}	break;    case PHOTOMETRIC_SEPARATED: {	uint16 inkset;	TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset);	if (inkset != INKSET_CMYK) {	    sprintf(emsg, "Sorry, can not handle separated image with %s=%d",		"InkSet", inkset);	    return (0);	}	if (img->samplesperpixel < 4) {	    sprintf(emsg, "Sorry, can not handle separated image with %s=%d",		"Samples/pixel", img->samplesperpixel);	    return (0);	}	break;    }    case PHOTOMETRIC_LOGL:	if (compress != COMPRESSION_SGILOG) {	    sprintf(emsg, "Sorry, LogL data must have %s=%d",		"Compression", COMPRESSION_SGILOG);	    return (0);	}	TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_8BIT);	img->photometric = PHOTOMETRIC_MINISBLACK;	/* little white lie */	img->bitspersample = 8;	break;    case PHOTOMETRIC_LOGLUV:	if (compress != COMPRESSION_SGILOG && compress != COMPRESSION_SGILOG24) {	    sprintf(emsg, "Sorry, LogLuv data must have %s=%d or %d",		"Compression", COMPRESSION_SGILOG, COMPRESSION_SGILOG24);	    return (0);	}	if (planarconfig != PLANARCONFIG_CONTIG) {	    sprintf(emsg, "Sorry, can not handle LogLuv images with %s=%d",		"Planarconfiguration", planarconfig);	    return (0);	}	TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_8BIT);	img->photometric = PHOTOMETRIC_RGB;		/* little white lie */	img->bitspersample = 8;	break;    default:	sprintf(emsg, "Sorry, can not handle image with %s=%d",	    photoTag, img->photometric);	return (0);    }    img->Map = NULL;    img->BWmap = NULL;    img->PALmap = NULL;    img->ycbcr = NULL;    TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &img->width);    TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &img->height);    TIFFGetFieldDefaulted(tif, TIFFTAG_ORIENTATION, &img->orientation);    img->isContig =	!(planarconfig == PLANARCONFIG_SEPARATE && colorchannels > 1);    if (img->isContig) {	img->get = TIFFIsTiled(tif) ? gtTileContig : gtStripContig;	(void) pickTileContigCase(img);    } else {	img->get = TIFFIsTiled(tif) ? gtTileSeparate : gtStripSeparate;	(void) pickTileSeparateCase(img);    }    return (1);}intTIFFRGBAImageGet(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h){    if (img->get == NULL) {	TIFFError(TIFFFileName(img->tif), "No \"get\" routine setup");	return (0);    }    if (img->put.any == NULL) {	TIFFError(TIFFFileName(img->tif),	    "No \"put\" routine setupl; probably can not handle image format");	return (0);    }    return (*img->get)(img, raster, w, h);}/* * Read the specified image into an ABGR-format raster. */intTIFFReadRGBAImage(TIFF* tif,    uint32 rwidth, uint32 rheight, uint32* raster, int stop){    char emsg[1024];    TIFFRGBAImage img;    int ok;    if (TIFFRGBAImageBegin(&img, tif, stop, emsg)) {	/* XXX verify rwidth and rheight against width and height */	ok = TIFFRGBAImageGet(&img, raster+(rheight-img.height)*rwidth,	    rwidth, img.height);	TIFFRGBAImageEnd(&img);    } else {	TIFFError(TIFFFileName(tif), emsg);	ok = 0;    }    return (ok);}static uint32setorientation(TIFFRGBAImage* img, uint32 h){    TIFF* tif = img->tif;    uint32 y;    switch (img->orientation) {    case ORIENTATION_BOTRIGHT:    case ORIENTATION_RIGHTBOT:	/* XXX */    case ORIENTATION_LEFTBOT:	/* XXX */	TIFFWarning(TIFFFileName(tif), "using bottom-left orientation");	img->orientation = ORIENTATION_BOTLEFT;	/* fall thru... */    case ORIENTATION_BOTLEFT:	y = 0;	break;    case ORIENTATION_TOPRIGHT:    case ORIENTATION_RIGHTTOP:	/* XXX */    case ORIENTATION_LEFTTOP:	/* XXX */    default:	TIFFWarning(TIFFFileName(tif), "using top-left orientation");	img->orientation = ORIENTATION_TOPLEFT;	/* fall thru... */    case ORIENTATION_TOPLEFT:	y = h-1;	break;    }    return (y);}/* * 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;    uint16 orientation;    uint32 col, row, y, rowstoread, ret = 1;    uint32 pos;    uint32 tw, th;    u_char* buf;    int32 fromskew, toskew;    uint32 nrow;     buf = (u_char*) _TIFFmalloc(TIFFTileSize(tif));    if (buf == 0) {	TIFFError(TIFFFileName(tif), "No space for tile buffer");	return (0);    }    TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);    TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);    y = setorientation(img, h);    orientation = img->orientation;    toskew = -(int32) (orientation == ORIENTATION_TOPLEFT ? tw+w : 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)

⌨️ 快捷键说明

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