This is tiffcp.c in view mode; [Download] [Up]
#ifndef lint static char rcsid[] = "/mode/users/src/master/tiff/tools/tiffcp.c,v 1.1.1.1 1994/04/01 17:15:36 fedor Exp"; #endif /* * Copyright (c) 1988, 1989, 1990, 1991, 1992 Sam Leffler * Copyright (c) 1991, 1992 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 "tiffio.h" typedef unsigned char u_char; typedef unsigned short u_short; typedef unsigned int u_int; typedef unsigned long u_long; #if defined(VMS) #define unlink delete #endif #define streq(a,b) (strcmp(a,b) == 0) #define CopyField(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 short config; static u_short compression; static u_short predictor; static u_short fillorder; static long rowsperstrip; static long g3opts; static int ignore = 0; /* if true, ignore read errors */ static char *filename; static int tiffcp(); static int cpContig2ContigByRow(); static int cpContig2SeparateByRow(); static int cpSeparate2ContigByRow(); static int cpSeparate2SeparateByRow(); static int cpDecodedStrips(); static void usage(); main(argc, argv) char *argv[]; { short defconfig = -1; u_short defcompression = -1; u_short defpredictor = 0; u_short deffillorder = 0; long defrowsperstrip = -1; long defg3opts = 0; TIFF *in, *out; argc--, argv++; if (argc < 2) usage(); for (; argc > 2 && argv[0][0] == '-'; argc--, argv++) { if (streq(argv[0], "-none")) { defcompression = COMPRESSION_NONE; continue; } if (streq(argv[0], "-packbits")) { defcompression = COMPRESSION_PACKBITS; continue; } if (streq(argv[0], "-lzw")) { defcompression = COMPRESSION_LZW; continue; } if (streq(argv[0], "-g3")) { defcompression = COMPRESSION_CCITTFAX3; continue; } if (streq(argv[0], "-g4")) { defcompression = COMPRESSION_CCITTFAX4; continue; } if (streq(argv[0], "-contig")) { defconfig = PLANARCONFIG_CONTIG; continue; } if (streq(argv[0], "-separate")) { defconfig = PLANARCONFIG_SEPARATE; continue; } if (streq(argv[0], "-lsb2msb")) { deffillorder = FILLORDER_LSB2MSB; continue; } if (streq(argv[0], "-msb2lsb")) { deffillorder = FILLORDER_MSB2LSB; continue; } if (streq(argv[0], "-rowsperstrip")) { argc--, argv++; defrowsperstrip = atoi(argv[0]); continue; } if (streq(argv[0], "-2d")) { defg3opts = GROUP3OPT_2DENCODING; continue; } if (streq(argv[0], "-fill")) { defg3opts |= GROUP3OPT_FILLBITS; continue; } if (streq(argv[0], "-predictor")) { argc--, argv++; defpredictor = atoi(argv[0]); continue; } if (streq(argv[0], "-ignore")) { ignore = 1; continue; } usage(); } out = TIFFOpen(argv[argc-1], "w"); if (out == NULL) exit(-2); for (; argc > 1; argc--, argv++) { in = TIFFOpen(filename = argv[0], "r"); if (in != NULL) { do { config = defconfig; compression = defcompression; predictor = defpredictor; fillorder = deffillorder; rowsperstrip = defrowsperstrip; g3opts = defg3opts; if (!tiffcp(in, out) || !TIFFWriteDirectory(out)) goto bad; } while (TIFFReadDirectory(in)); (void) TIFFClose(in); } } (void) TIFFClose(out); exit(0); bad: unlink(TIFFFileName(out)); exit(1); } static CheckAndCorrectColormap(n, r, g, b) int n; u_short *r, *g, *b; { int i; for (i = 0; i < n; i++) if (r[i] >= 256 || g[i] >= 256 || b[i] >= 256) return; TIFFWarning(filename, "Scaling 8-bit colormap"); #define CVT(x) (((x) * ((1L<<16)-1)) / 255) for (i = 0; i < n; i++) { r[i] = CVT(r[i]); g[i] = CVT(g[i]); b[i] = CVT(b[i]); } #undef CVT } static struct cpTag { long tag; short count; TIFFDataType type; } tags[] = { { 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,-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, -1,TIFF_RATIONAL }, { TIFFTAG_YCBCRSUBSAMPLING, 2, TIFF_SHORT }, { TIFFTAG_YCBCRPOSITIONING, 1, TIFF_SHORT }, { TIFFTAG_REFERENCEBLACKWHITE, -1,TIFF_RATIONAL }, { TIFFTAG_MATTEING, 1, TIFF_SHORT }, }; #define NTAGS (sizeof (tags) / sizeof (tags[0])) static void cpOtherTags(in, out) TIFF *in, *out; { struct cpTag *p; short shortv, shortv2; float floatv, *floatav; char *stringv; u_long longv; for (p = tags; p < &tags[NTAGS]; p++) switch (p->type) { case TIFF_SHORT: if (p->count == 1) { CopyField(p->tag, shortv); } else if (p->count == 2) { CopyField2(p->tag, shortv, shortv2); } break; case TIFF_LONG: CopyField(p->tag, longv); break; case TIFF_RATIONAL: if (p->count == 1) { CopyField(p->tag, floatv); } else if (p->count == -1) { CopyField(p->tag, floatav); } break; case TIFF_ASCII: CopyField(p->tag, stringv); break; } } static int tiffcp(in, out) TIFF *in, *out; { short bitspersample, samplesperpixel, shortv, bystrip; u_long w, l; CopyField(TIFFTAG_IMAGEWIDTH, w); CopyField(TIFFTAG_IMAGELENGTH, l); CopyField(TIFFTAG_BITSPERSAMPLE, bitspersample); if (compression != (u_short)-1) TIFFSetField(out, TIFFTAG_COMPRESSION, compression); else CopyField(TIFFTAG_COMPRESSION, compression); if (fillorder != 0) TIFFSetField(out, TIFFTAG_FILLORDER, fillorder); else CopyField(TIFFTAG_FILLORDER, shortv); CopyField(TIFFTAG_SAMPLESPERPIXEL, samplesperpixel); if (rowsperstrip < 0) { /* * RowsPerStrip is left unspecified: use either the * value from the input image or, if nothing is defined, * something that approximates 8Kbyte strips. */ if (!TIFFGetField(in, TIFFTAG_ROWSPERSTRIP, &rowsperstrip)) rowsperstrip = (8*1024)/TIFFScanlineSize(out); } if (rowsperstrip == 0) rowsperstrip = 1L; TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, rowsperstrip); if (config != -1) TIFFSetField(out, TIFFTAG_PLANARCONFIG, config); else CopyField(TIFFTAG_PLANARCONFIG, config); if (g3opts != 0) TIFFSetField(out, TIFFTAG_GROUP3OPTIONS, g3opts); else CopyField(TIFFTAG_GROUP3OPTIONS, g3opts); if (samplesperpixel <= 4) { u_short *tr, *tg, *tb, *ta; CopyField4(TIFFTAG_TRANSFERFUNCTION, tr, tg, tb, ta); } if (predictor != 0) TIFFSetField(out, TIFFTAG_PREDICTOR, predictor); else CopyField(TIFFTAG_PREDICTOR, predictor); { u_short *red, *green, *blue; if (TIFFGetField(in, TIFFTAG_COLORMAP, &red, &green, &blue)) { CheckAndCorrectColormap(1<<bitspersample, red, green, blue); TIFFSetField(out, TIFFTAG_COLORMAP, red, green, blue); } } /* TileWidth & TileLength */ /* SMinSampleValue & SMaxSampleValue */ /* JPEG stuff */ cpOtherTags(in, out); (void) TIFFGetField(in, TIFFTAG_PLANARCONFIG, &shortv); if (shortv != config && bitspersample != 8 && samplesperpixel > 1) { fprintf(stderr, "Can't handle different planar configuration w/ bits/sample != 8\n"); return (0); } { long irps = -1L; TIFFGetField(in, TIFFTAG_ROWSPERSTRIP, &irps); bystrip = (rowsperstrip == irps); } #define pack(a,b,c) ((u_long)(((a)<<9)|((b)<<1)|(c))) switch (pack(shortv, config, bystrip)) { case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_CONTIG, 0): return (cpContig2ContigByRow(in, out, l)); case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_CONTIG, 1): return (cpDecodedStrips(in, out, l)); case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_SEPARATE, 0): case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_SEPARATE, 1): return (cpSeparate2SeparateByRow(in, out, l, samplesperpixel)); case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_SEPARATE, 0): case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_SEPARATE, 1): return (cpContig2SeparateByRow(in, out, l, samplesperpixel, w)); case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_CONTIG, 0): case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_CONTIG, 1): return (cpSeparate2ContigByRow(in, out, l, samplesperpixel, w)); default: fprintf(stderr, "tiffcp: %s: Unknown planar configuration (in=%d out=%d).\n", TIFFFileName(in), shortv, config); return (0); } /*NOTREACHED*/ } static int cpContig2ContigByRow(in, out, imagelength) TIFF *in, *out; u_long imagelength; { u_char *buf = (u_char *)malloc(TIFFScanlineSize(in)); u_long row; for (row = 0; row < imagelength; row++) { if (TIFFReadScanline(in, buf, row, 0) < 0 && !ignore) goto done; if (TIFFWriteScanline(out, buf, row, 0) < 0) goto bad; } done: free(buf); return (1); bad: free(buf); return (0); } static int cpDecodedStrips(in, out, h) TIFF *in, *out; u_long h; { u_long stripsize = TIFFStripSize(in); u_char *buf = (u_char *)malloc(stripsize); if (buf) { u_int s, ns = TIFFNumberOfStrips(in); u_long row = 0; for (s = 0; s < ns; s++) { u_int cc = (row + rowsperstrip > h) ? TIFFVStripSize(in, h - row) : stripsize; if (TIFFReadEncodedStrip(in, s, buf, cc) < 0 && !ignore) break; if (TIFFWriteEncodedStrip(out, s, buf, cc) < 0) { free(buf); return (0); } row += rowsperstrip; } free(buf); return (1); } return (0); } static int cpSeparate2SeparateByRow(in, out, imagelength, samplesperpixel) TIFF *in, *out; u_long imagelength; short samplesperpixel; { u_char *buf = (u_char *)malloc(TIFFScanlineSize(in)); u_long row; int s; for (s = 0; s < samplesperpixel; s++) { for (row = 0; row < imagelength; row++) { if (TIFFReadScanline(in, buf, row, s) < 0 && !ignore) goto done; if (TIFFWriteScanline(out, buf, row, s) < 0) goto bad; } } done: free(buf); return (1); bad: free(buf); return (0); } static int cpContig2SeparateByRow(in, out, imagelength, samplesperpixel, imagewidth) TIFF *in, *out; u_long imagelength; short samplesperpixel; u_long imagewidth; { u_char *inbuf = (u_char *)malloc(TIFFScanlineSize(in)); u_char *outbuf = (u_char *)malloc(TIFFScanlineSize(out)); register u_char *inp, *outp; register u_long n; u_long row; int s; /* unpack channels */ for (s = 0; s < samplesperpixel; s++) { for (row = 0; row < imagelength; row++) { if (TIFFReadScanline(in, inbuf, row, 0) < 0 && !ignore) goto done; inp = inbuf + s; outp = outbuf; for (n = imagewidth; n-- > 0;) { *outp++ = *inp; inp += samplesperpixel; } if (TIFFWriteScanline(out, outbuf, row, s) < 0) goto bad; } } done: if (inbuf) free(inbuf); if (outbuf) free(outbuf); return (1); bad: if (inbuf) free(inbuf); if (outbuf) free(outbuf); return (0); } static int cpSeparate2ContigByRow(in, out, imagelength, samplesperpixel, imagewidth) TIFF *in, *out; u_long imagelength; int samplesperpixel; u_long imagewidth; { u_char *inbuf = (u_char *)malloc(TIFFScanlineSize(in)); u_char *outbuf = (u_char *)malloc(TIFFScanlineSize(out)); register u_char *inp, *outp; register u_long n; u_long row; int s; for (row = 0; row < imagelength; row++) { /* merge channels */ for (s = 0; s < samplesperpixel; s++) { if (TIFFReadScanline(in, inbuf, row, s) < 0 && !ignore) goto done; inp = inbuf; outp = outbuf + s; for (n = imagewidth; n-- > 0;) { *outp = *inp++; outp += samplesperpixel; } } if (TIFFWriteScanline(out, outbuf, row, 0) < 0) goto bad; } done: if (inbuf) free(inbuf); if (outbuf) free(outbuf); return (1); bad: if (inbuf) free(inbuf); if (outbuf) free(outbuf); return (0); } static void usage() { fprintf(stderr, "usage: tiffcp [options] input... output\n"); fprintf(stderr, "where options are:\n"); fprintf(stderr, " -contig\tpack samples contiguously (e.g. RGBRGB...)\n"); fprintf(stderr, " -separate\tstore samples separately (e.g. RRR...GGG...BBB...)\n"); fprintf(stderr, "\n"); fprintf(stderr, " -lsb2msb\tforce lsb-to-msb FillOrder for output\n"); fprintf(stderr, " -msb2lsb\tforce msb-to-lsb FillOrder for output\n"); fprintf(stderr, "\n"); fprintf(stderr, " -lzw\t\tcompress output with Lempel-Ziv & Welch encoding\n"); fprintf(stderr, " -packbits\tcompress output with packbits encoding\n"); fprintf(stderr, " -g3\t\tcompress output with CCITT Group 3 encoding\n"); fprintf(stderr, " -g4\t\tcompress output with CCITT Group 4 encoding\n"); fprintf(stderr, " -none\t\tuse no compression algorithm on output\n"); fprintf(stderr, "\n"); fprintf(stderr, " -2d\t\tuse 2d encoding when compressing with Group 3\n"); fprintf(stderr, " -fill\t\tzero-fill scanlines when compressing with Group 3\n"); fprintf(stderr, "\n"); fprintf(stderr, " -rowsperstrip #\tmake each strip have no more than # rows\n"); fprintf(stderr, " -predictor\tset LZW predictor value\n"); fprintf(stderr, " -ignore\tignore read errors\n"); exit(-1); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.