📄 thumbnail.c
字号:
return (0); } return (1);}static uint16 photometric; /* current photometric of raster */static uint16 filterWidth; /* filter width in pixels */static uint16 stepSrcWidth; /* src image stepping width */static uint16 stepDstWidth; /* dest stepping width */static uint8* src0; /* horizontal bit stepping (start) */static uint8* src1; /* horizontal bit stepping (middle) */static uint8* src2; /* horizontal bit stepping (end) */static uint16* rowoff; /* row offset for stepping */static uint8 cmap[256]; /* colormap indexes */static uint8 bits[256]; /* count of bits set */static voidsetupBitsTables(){ int i; for (i = 0; i < 256; i++) { int n = 0; if (i&0x01) n++; if (i&0x02) n++; if (i&0x04) n++; if (i&0x08) n++; if (i&0x10) n++; if (i&0x20) n++; if (i&0x40) n++; if (i&0x80) n++; bits[i] = n; }}static int clamp(float v, int low, int high) { return (v < low ? low : v > high ? high : (int)v); }#ifndef M_E#define M_E 2.7182818284590452354#endifstatic voidexpFill(float pct[], uint32 p, uint32 n){ uint32 i; uint32 c = (p * n) / 100; for (i = 1; i < c; i++) pct[i] = 1-exp(i/((double)(n-1)))/ M_E; for (; i < n; i++) pct[i] = 0.;}static voidsetupCmap(){ float pct[256]; /* known to be large enough */ uint32 i; pct[0] = 1; /* force white */ switch (contrast) { case EXP50: expFill(pct, 50, 256); break; case EXP60: expFill(pct, 60, 256); break; case EXP70: expFill(pct, 70, 256); break; case EXP80: expFill(pct, 80, 256); break; case EXP90: expFill(pct, 90, 256); break; case EXP: expFill(pct, 100, 256); break; case LINEAR: for (i = 1; i < 256; i++) pct[i] = 1-((float)i)/(256-1); break; } switch (photometric) { case PHOTOMETRIC_MINISWHITE: for (i = 0; i < 256; i++) cmap[i] = clamp(255*pct[(256-1)-i], 0, 255); break; case PHOTOMETRIC_MINISBLACK: for (i = 0; i < 256; i++) cmap[i] = clamp(255*pct[i], 0, 255); break; }}static voidinitScale(){ src0 = (uint8*) _TIFFmalloc(sizeof (uint8) * tnw); src1 = (uint8*) _TIFFmalloc(sizeof (uint8) * tnw); src2 = (uint8*) _TIFFmalloc(sizeof (uint8) * tnw); rowoff = (uint16*) _TIFFmalloc(sizeof (uint16) * tnw); filterWidth = 0; stepDstWidth = stepSrcWidth = 0; setupBitsTables();}/* * Calculate the horizontal accumulation parameteres * according to the widths of the src and dst images. */static voidsetupStepTables(uint16 sw){ if (stepSrcWidth != sw || stepDstWidth != tnw) { int step = sw; int limit = tnw; int err = 0; uint32 sx = 0; uint32 x; int fw; uint8 b; for (x = 0; x < tnw; x++) { uint32 sx0 = sx; err += step; while (err >= limit) { err -= limit; sx++; } rowoff[x] = sx0 >> 3; fw = sx - sx0; /* width */ b = (fw < 8) ? 0xff<<(8-fw) : 0xff; src0[x] = b >> (sx0&7); fw -= 8 - (sx0&7); if (fw < 0) fw = 0; src1[x] = fw >> 3; fw -= (fw>>3)<<3; src2[x] = 0xff << (8-fw); } stepSrcWidth = sw; stepDstWidth = tnw; }}static voidsetrow(uint8* row, int nrows, const uint8* rows[]){ uint32 x; uint32 area = nrows * filterWidth; for (x = 0; x < tnw; x++) { uint32 mask0 = src0[x]; uint32 fw = src1[x]; uint32 mask1 = src1[x]; uint32 off = rowoff[x]; uint32 acc = 0; uint32 y, i; for (y = 0; y < nrows; y++) { const uint8* src = rows[y] + off; acc += bits[*src++ & mask0]; switch (fw) { default: for (i = fw; i > 8; i--) acc += bits[*src++]; /* fall thru... */ case 8: acc += bits[*src++]; case 7: acc += bits[*src++]; case 6: acc += bits[*src++]; case 5: acc += bits[*src++]; case 4: acc += bits[*src++]; case 3: acc += bits[*src++]; case 2: acc += bits[*src++]; case 1: acc += bits[*src++]; case 0: break; } acc += bits[*src & mask1]; } *row++ = cmap[(255*acc)/area]; }}/* * Install the specified image. The * image is resized to fit the display page using * a box filter. The resultant pixels are mapped * with a user-selectable contrast curve. */static voidsetImage1(const uint8* br, uint32 rw, uint32 rh){ int step = rh; int limit = tnh; int err = 0; int bpr = howmany(rw,8); uint32 sy = 0; uint8* row = thumbnail; uint32 dy; for (dy = 0; dy < tnh; dy++) { const uint8* rows[256]; int nrows = 1; rows[0] = br + bpr*sy; err += step; while (err >= limit) { err -= limit; sy++; if (err >= limit) rows[nrows++] = br + bpr*sy; } setrow(row, nrows, rows); row += tnw; }}static voidsetImage(const uint8* br, uint32 rw, uint32 rh){ filterWidth = (uint16) ceil((double) rw / (double) tnw); setupStepTables(rw); setImage1(br, rw, rh);}static intgenerateThumbnail(TIFF* in, TIFF* out){ unsigned char* raster; unsigned char* rp; uint32 sw, sh, rps; uint16 bps, spp; tsize_t rowsize, rastersize; tstrip_t s, ns = TIFFNumberOfStrips(in); uint32 diroff[1]; TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &sw); TIFFGetField(in, TIFFTAG_IMAGELENGTH, &sh); TIFFGetFieldDefaulted(in, TIFFTAG_BITSPERSAMPLE, &bps); TIFFGetFieldDefaulted(in, TIFFTAG_SAMPLESPERPIXEL, &spp); TIFFGetFieldDefaulted(in, TIFFTAG_ROWSPERSTRIP, &rps); if (spp != 1 || bps != 1) return (0); rowsize = TIFFScanlineSize(in); rastersize = sh * rowsize; raster = (unsigned char*)_TIFFmalloc(rastersize); rp = raster; for (s = 0; s < ns; s++) { (void) TIFFReadEncodedStrip(in, s, rp, -1); rp += rps * rowsize; } TIFFGetField(in, TIFFTAG_PHOTOMETRIC, &photometric); setupCmap(); setImage(raster, sw, sh); _TIFFfree(raster); TIFFSetField(out, TIFFTAG_SUBFILETYPE, FILETYPE_REDUCEDIMAGE); TIFFSetField(out, TIFFTAG_IMAGEWIDTH, (uint32) tnw); TIFFSetField(out, TIFFTAG_IMAGELENGTH, (uint32) tnh); TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, (uint16) 8); TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, (uint16) 1); TIFFSetField(out, TIFFTAG_COMPRESSION, COMPRESSION_PACKBITS); TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISWHITE); TIFFSetField(out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT); cpTag(in, out, TIFFTAG_SOFTWARE, (uint16) -1, TIFF_ASCII); cpTag(in, out, TIFFTAG_IMAGEDESCRIPTION, (uint16) -1, TIFF_ASCII); cpTag(in, out, TIFFTAG_DATETIME, (uint16) -1, TIFF_ASCII); cpTag(in, out, TIFFTAG_HOSTCOMPUTER, (uint16) -1, TIFF_ASCII); diroff[0] = 0; TIFFSetField(out, TIFFTAG_SUBIFD, 1, diroff); return (TIFFWriteEncodedStrip(out, 0, thumbnail, tnw*tnh) != -1 && TIFFWriteDirectory(out) != -1);}char* stuff[] = {"usage: thumbnail [options] input.tif output.tif","where options are:"," -h # specify thumbnail image height (default is 274)"," -w # specify thumbnail image width (default is 216)",""," -c linear use linear contrast curve"," -c exp50 use 50% exponential contrast curve"," -c exp60 use 60% exponential contrast curve"," -c exp70 use 70% exponential contrast curve"," -c exp80 use 80% exponential contrast curve"," -c exp90 use 90% exponential contrast curve"," -c exp use pure exponential contrast curve",NULL};static voidusage(void){ char buf[BUFSIZ]; int i; setbuf(stderr, buf); fprintf(stderr, "%s\n\n", TIFFGetVersion()); for (i = 0; stuff[i] != NULL; i++) fprintf(stderr, "%s\n", stuff[i]); exit(-1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -