📄 thumbnail.c
字号:
/* $Header: /cvsroot/osrs/libtiff/tools/thumbnail.c,v 1.4 2003/07/03 12:27:17 dron Exp $ *//* * Copyright (c) 1994-1997 Sam Leffler * Copyright (c) 1994-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. */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>#include "tiffio.h"#define streq(a,b) (strcasecmp(a,b) == 0)#ifndef howmany#define howmany(x, y) (((x)+((y)-1))/(y))#endiftypedef enum { EXP50, EXP60, EXP70, EXP80, EXP90, EXP, LINEAR} Contrast;static uint32 tnw = 216; /* thumbnail width */static uint32 tnh = 274; /* thumbnail height */static Contrast contrast = LINEAR; /* current contrast */static uint8* thumbnail;static int cpIFD(TIFF*, TIFF*);static int generateThumbnail(TIFF*, TIFF*);static void initScale();static void usage(void);extern char* optarg;extern int optind;intmain(int argc, char* argv[]){ TIFF* in; TIFF* out; int c; while ((c = getopt(argc, argv, "w:h:c:")) != -1) { switch (c) { case 'w': tnw = strtoul(optarg, NULL, 0); break; case 'h': tnh = strtoul(optarg, NULL, 0); break; case 'c': contrast = streq(optarg, "exp50") ? EXP50 : streq(optarg, "exp60") ? EXP60 : streq(optarg, "exp70") ? EXP70 : streq(optarg, "exp80") ? EXP80 : streq(optarg, "exp90") ? EXP90 : streq(optarg, "exp") ? EXP : streq(optarg, "linear")? LINEAR : EXP; break; default: usage(); } } if (argc-optind != 2) usage(); thumbnail = (uint8*) _TIFFmalloc(tnw * tnh); out = TIFFOpen(argv[optind+1], "w"); if (out == NULL) return (-2); in = TIFFOpen(argv[optind], "r"); if (in != NULL) { initScale(); do { if (!generateThumbnail(in, out)) goto bad; if (!cpIFD(in, out) || !TIFFWriteDirectory(out)) goto bad; } while (TIFFReadDirectory(in)); (void) TIFFClose(in); } (void) TIFFClose(out); return (0);bad: (void) TIFFClose(out); return (1);}#define CopyField1(tag, v) \ if (TIFFGetField(in, tag, &v)) TIFFSetField(out, tag, v)#define CopyField2(tag, v1, v2) \ if (TIFFGetField(in, tag, &v1, &v2)) TIFFSetField(out, tag, v1, v2)#define CopyField3(tag, v1, v2, v3) \ if (TIFFGetField(in, tag, &v1, &v2, &v3)) TIFFSetField(out, tag, v1, v2, v3)#define CopyField4(tag, v1, v2, v3, v4) \ if (TIFFGetField(in, tag, &v1, &v2, &v3, &v4)) TIFFSetField(out, tag, v1, v2, v3, v4)static voidcpTag(TIFF* in, TIFF* out, uint16 tag, uint16 count, TIFFDataType type){ uint16 shortv, shortv2, *shortav; float floatv, *floatav; char *stringv; uint32 longv; switch (type) { case TIFF_SHORT: if (count == 1) { CopyField1(tag, shortv); } else if (count == 2) { CopyField2(tag, shortv, shortv2); } else if (count == (uint16) -1) { CopyField2(tag, shortv, shortav); } break; case TIFF_LONG: CopyField1(tag, longv); break; case TIFF_RATIONAL: if (count == 1) { CopyField1(tag, floatv); } else if (count == (uint16) -1) { CopyField1(tag, floatav); } break; case TIFF_ASCII: CopyField1(tag, stringv); break; }}#undef CopyField4#undef CopyField3#undef CopyField2#undef CopyField1static struct cpTag { uint16 tag; uint16 count; TIFFDataType type;} tags[] = { { TIFFTAG_IMAGEWIDTH, 1, TIFF_LONG }, { TIFFTAG_IMAGELENGTH, 1, TIFF_LONG }, { TIFFTAG_BITSPERSAMPLE, 1, TIFF_SHORT }, { TIFFTAG_COMPRESSION, 1, TIFF_SHORT }, { TIFFTAG_FILLORDER, 1, TIFF_SHORT }, { TIFFTAG_SAMPLESPERPIXEL, 1, TIFF_SHORT }, { TIFFTAG_ROWSPERSTRIP, 1, TIFF_LONG }, { TIFFTAG_PLANARCONFIG, 1, TIFF_SHORT }, { TIFFTAG_GROUP3OPTIONS, 1, TIFF_LONG }, { TIFFTAG_SUBFILETYPE, 1, TIFF_LONG }, { TIFFTAG_PHOTOMETRIC, 1, TIFF_SHORT }, { TIFFTAG_THRESHHOLDING, 1, TIFF_SHORT }, { TIFFTAG_DOCUMENTNAME, 1, TIFF_ASCII }, { TIFFTAG_IMAGEDESCRIPTION, 1, TIFF_ASCII }, { TIFFTAG_MAKE, 1, TIFF_ASCII }, { TIFFTAG_MODEL, 1, TIFF_ASCII }, { TIFFTAG_ORIENTATION, 1, TIFF_SHORT }, { TIFFTAG_MINSAMPLEVALUE, 1, TIFF_SHORT }, { TIFFTAG_MAXSAMPLEVALUE, 1, TIFF_SHORT }, { TIFFTAG_XRESOLUTION, 1, TIFF_RATIONAL }, { TIFFTAG_YRESOLUTION, 1, TIFF_RATIONAL }, { TIFFTAG_PAGENAME, 1, TIFF_ASCII }, { TIFFTAG_XPOSITION, 1, TIFF_RATIONAL }, { TIFFTAG_YPOSITION, 1, TIFF_RATIONAL }, { TIFFTAG_GROUP4OPTIONS, 1, TIFF_LONG }, { TIFFTAG_RESOLUTIONUNIT, 1, TIFF_SHORT }, { TIFFTAG_PAGENUMBER, 2, TIFF_SHORT }, { TIFFTAG_SOFTWARE, 1, TIFF_ASCII }, { TIFFTAG_DATETIME, 1, TIFF_ASCII }, { TIFFTAG_ARTIST, 1, TIFF_ASCII }, { TIFFTAG_HOSTCOMPUTER, 1, TIFF_ASCII }, { TIFFTAG_WHITEPOINT, 1, TIFF_RATIONAL }, { TIFFTAG_PRIMARYCHROMATICITIES, (uint16) -1,TIFF_RATIONAL }, { TIFFTAG_HALFTONEHINTS, 2, TIFF_SHORT }, { TIFFTAG_BADFAXLINES, 1, TIFF_LONG }, { TIFFTAG_CLEANFAXDATA, 1, TIFF_SHORT }, { TIFFTAG_CONSECUTIVEBADFAXLINES, 1, TIFF_LONG }, { TIFFTAG_INKSET, 1, TIFF_SHORT }, { TIFFTAG_INKNAMES, 1, TIFF_ASCII }, { TIFFTAG_DOTRANGE, 2, TIFF_SHORT }, { TIFFTAG_TARGETPRINTER, 1, TIFF_ASCII }, { TIFFTAG_SAMPLEFORMAT, 1, TIFF_SHORT }, { TIFFTAG_YCBCRCOEFFICIENTS, (uint16) -1,TIFF_RATIONAL }, { TIFFTAG_YCBCRSUBSAMPLING, 2, TIFF_SHORT }, { TIFFTAG_YCBCRPOSITIONING, 1, TIFF_SHORT }, { TIFFTAG_REFERENCEBLACKWHITE, (uint16) -1,TIFF_RATIONAL }, { TIFFTAG_EXTRASAMPLES, (uint16) -1, TIFF_SHORT },};#define NTAGS (sizeof (tags) / sizeof (tags[0]))static voidcpTags(TIFF* in, TIFF* out){ struct cpTag *p; for (p = tags; p < &tags[NTAGS]; p++) cpTag(in, out, p->tag, p->count, p->type);}#undef NTAGSstatic intcpStrips(TIFF* in, TIFF* out){ tsize_t bufsize = TIFFStripSize(in); unsigned char *buf = (unsigned char *)_TIFFmalloc(bufsize); if (buf) { tstrip_t s, ns = TIFFNumberOfStrips(in); uint32 *bytecounts; TIFFGetField(in, TIFFTAG_STRIPBYTECOUNTS, &bytecounts); for (s = 0; s < ns; s++) { if (bytecounts[s] > bufsize) { buf = (unsigned char *)_TIFFrealloc(buf, bytecounts[s]); if (!buf) return (0); bufsize = bytecounts[s]; } if (TIFFReadRawStrip(in, s, buf, bytecounts[s]) < 0 || TIFFWriteRawStrip(out, s, buf, bytecounts[s]) < 0) { _TIFFfree(buf); return (0); } } _TIFFfree(buf); return (1); } return (0);}static intcpTiles(TIFF* in, TIFF* out){ tsize_t bufsize = TIFFTileSize(in); unsigned char *buf = (unsigned char *)_TIFFmalloc(bufsize); if (buf) { ttile_t t, nt = TIFFNumberOfTiles(in); uint32 *bytecounts; TIFFGetField(in, TIFFTAG_TILEBYTECOUNTS, &bytecounts); for (t = 0; t < nt; t++) { if (bytecounts[t] > bufsize) { buf = (unsigned char *)_TIFFrealloc(buf, bytecounts[t]); if (!buf) return (0); bufsize = bytecounts[t]; } if (TIFFReadRawTile(in, t, buf, bytecounts[t]) < 0 || TIFFWriteRawTile(out, t, buf, bytecounts[t]) < 0) { _TIFFfree(buf); return (0); } } _TIFFfree(buf); return (1); } return (0);}static intcpIFD(TIFF* in, TIFF* out){ cpTags(in, out); if (TIFFIsTiled(in)) { if (!cpTiles(in, out)) return (0); } else { if (!cpStrips(in, out))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -