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

📄 tiff.c

📁 linux下开源图片codec
💻 C
字号:
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <inttypes.h>#include <tiffio.h>#include "loader.h"#ifdef USE_X11# include "viewer.h"#endifstruct tiff_state {    TIFF*          tif;    char           emsg[1024];    tdir_t         ndirs;     /* Number of directories                     */                              /* (could be interpreted as number of pages) */    uint32         width,height;    uint16         config,nsamples,depth,fillorder,photometric;    uint32*        row;    uint32*        image;    uint16         resunit;    float          xres,yres;};static void*tiff_init(FILE *fp, char *filename, unsigned int page,	  struct ida_image_info *i, int thumbnail){    struct tiff_state *h;    fclose(fp);    h = malloc(sizeof(*h));    memset(h,0,sizeof(*h));    TIFFSetWarningHandler(NULL);    h->tif = TIFFOpen(filename,"r");    if (NULL == h->tif)	goto oops;    /* Determine number of directories */    h->ndirs = 1;    while (TIFFReadDirectory(h->tif))        h->ndirs++;    i->npages = h->ndirs;    /* Select requested directory (page) */    if (!TIFFSetDirectory(h->tif, (tdir_t)page))        goto oops;        TIFFGetField(h->tif, TIFFTAG_IMAGEWIDTH,      &h->width);    TIFFGetField(h->tif, TIFFTAG_IMAGELENGTH,     &h->height);    TIFFGetField(h->tif, TIFFTAG_PLANARCONFIG,    &h->config);    TIFFGetField(h->tif, TIFFTAG_SAMPLESPERPIXEL, &h->nsamples);    TIFFGetField(h->tif, TIFFTAG_BITSPERSAMPLE,   &h->depth);    TIFFGetField(h->tif, TIFFTAG_FILLORDER,       &h->fillorder);    TIFFGetField(h->tif, TIFFTAG_PHOTOMETRIC,     &h->photometric);    h->row = malloc(TIFFScanlineSize(h->tif));    if (debug)	fprintf(stderr,"tiff: %" PRId32 "x%" PRId32 ", planar=%d, "		"nsamples=%d, depth=%d fo=%d pm=%d scanline=%" PRId32 "\n",		h->width,h->height,h->config,h->nsamples,h->depth,		h->fillorder,h->photometric,		TIFFScanlineSize(h->tif));    if (PHOTOMETRIC_PALETTE   == h->photometric  ||	PHOTOMETRIC_YCBCR     == h->photometric  ||	PHOTOMETRIC_SEPARATED == h->photometric  ||	TIFFIsTiled(h->tif)                      ||	(1 != h->depth  &&  8 != h->depth)) {	/* for the more difficuilt cases we let libtiff	 * do all the hard work.  Drawback is that we lose	 * progressive loading and decode everything here */	if (debug)	    fprintf(stderr,"tiff: reading whole image [TIFFReadRGBAImage]\n");	h->image=malloc(4*h->width*h->height);	TIFFReadRGBAImage(h->tif, h->width, h->height, h->image, 0);    } else {	if (debug)	    fprintf(stderr,"tiff: reading scanline by scanline\n");	h->row = malloc(TIFFScanlineSize(h->tif));    }    i->width  = h->width;    i->height = h->height;    if (TIFFGetField(h->tif, TIFFTAG_RESOLUTIONUNIT,  &h->resunit) &&	TIFFGetField(h->tif, TIFFTAG_XRESOLUTION,     &h->xres)    &&	TIFFGetField(h->tif, TIFFTAG_YRESOLUTION,     &h->yres)) {	switch (h->resunit) {	case RESUNIT_NONE:	    break;	case RESUNIT_INCH:	    i->dpi = h->xres;	    break;	case RESUNIT_CENTIMETER:	    i->dpi = res_cm_to_inch(h->xres);	    break;	}    }    return h; oops:    if (h->tif)	TIFFClose(h->tif);    free(h);    return NULL;}static voidtiff_read(unsigned char *dst, unsigned int line, void *data){    struct tiff_state *h = data;    int s,on,off;    if (h->image) {	/* loaded whole image using TIFFReadRGBAImage() */	uint32 *row = h->image + h->width * (h->height - line -1);	load_rgba(dst,(unsigned char*)row,h->width);	return;    }        if (h->config == PLANARCONFIG_CONTIG) {	TIFFReadScanline(h->tif, h->row, line, 0);    } else if (h->config == PLANARCONFIG_SEPARATE) {	for (s = 0; s < h->nsamples; s++)	    TIFFReadScanline(h->tif, h->row, line, s);    }    switch (h->nsamples) {    case 1:	if (1 == h->depth) {	    /* black/white */	    on = 0, off = 0;	    if (PHOTOMETRIC_MINISWHITE == h->photometric)		on = 0, off = 255;	    if (PHOTOMETRIC_MINISBLACK == h->photometric)		on = 255, off = 0;#if 0	    /* Huh?  Does TIFFReadScanline handle this already ??? */	    if (FILLORDER_MSB2LSB == h->fillorder)		load_bits_msb(dst,(unsigned char*)(h->row),h->width,on,off);	    else		load_bits_lsb(dst,(unsigned char*)(h->row),h->width,on,off);#else	    load_bits_msb(dst,(unsigned char*)(h->row),h->width,on,off);#endif	} else {	    /* grayscaled */	    load_gray(dst,(unsigned char*)(h->row),h->width);	}	break;    case 3:	/* rgb */	memcpy(dst,h->row,3*h->width);	break;    case 4:	/* rgb+alpha */	load_rgba(dst,(unsigned char*)(h->row),h->width);	break;    }}static voidtiff_done(void *data){    struct tiff_state *h = data;    TIFFClose(h->tif);    if (h->row)	free(h->row);    if (h->image)	free(h->image);    free(h);}static struct ida_loader tiff1_loader = {    magic: "MM\x00\x2a",    moff:  0,    mlen:  4,    name:  "libtiff",    init:  tiff_init,    read:  tiff_read,    done:  tiff_done,};static struct ida_loader tiff2_loader = {    magic: "II\x2a\x00",    moff:  0,    mlen:  4,    name:  "libtiff",    init:  tiff_init,    read:  tiff_read,    done:  tiff_done,};static void __init init_rd(void){    load_register(&tiff1_loader);    load_register(&tiff2_loader);}#ifdef USE_X11/* ---------------------------------------------------------------------- *//* save                                                                   */static inttiff_write(FILE *fp, struct ida_image *img){    TIFF          *TiffHndl;    tdata_t       buf;    unsigned int  y;    TiffHndl = TIFFFdOpen(fileno(fp),"42.tiff","w");    if (TiffHndl == NULL)	return -1;    TIFFSetField(TiffHndl, TIFFTAG_IMAGEWIDTH, img->i.width);    TIFFSetField(TiffHndl, TIFFTAG_IMAGELENGTH, img->i.height);    TIFFSetField(TiffHndl, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);    TIFFSetField(TiffHndl, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);    TIFFSetField(TiffHndl, TIFFTAG_BITSPERSAMPLE, 8);    TIFFSetField(TiffHndl, TIFFTAG_SAMPLESPERPIXEL, 3);    TIFFSetField(TiffHndl, TIFFTAG_ROWSPERSTRIP, 2);    TIFFSetField(TiffHndl, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);#if 0 /* fixme: make this configureable */    TIFFSetField(TiffHndl, TIFFTAG_COMPRESSION, COMPRESSION_LZW);    TIFFSetField(TiffHndl, TIFFTAG_PREDICTOR, 2);#endif    if (img->i.dpi) {	float dpi = img->i.dpi;	TIFFSetField(TiffHndl, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);	TIFFSetField(TiffHndl, TIFFTAG_XRESOLUTION,    dpi);	TIFFSetField(TiffHndl, TIFFTAG_YRESOLUTION,    dpi);    }    for (y = 0; y < img->i.height; y++) {	buf = img->data + 3*img->i.width*y;	TIFFWriteScanline(TiffHndl, buf, y, 0);    }    TIFFClose(TiffHndl);    return 0;}static struct ida_writer tiff_writer = {    label:  "TIFF",    ext:    { "tif", "tiff", NULL},    write:  tiff_write,};static void __init init_wr(void){    write_register(&tiff_writer);}#endif

⌨️ 快捷键说明

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