1 /* $Header: /cvs/maptools/cvsroot/libtiff/tools/tiffsplit.c,v 1.3 2003-07-26 03:46:08 warmerda Exp $ */ 2 3 /* 4 * Copyright (c) 1992-1997 Sam Leffler 5 * Copyright (c) 1992-1997 Silicon Graphics, Inc. 6 * 7 * Permission to use, copy, modify, distribute, and sell this software and 8 * its documentation for any purpose is hereby granted without fee, provided 9 * that (i) the above copyright notices and this permission notice appear in 10 * all copies of the software and related documentation, and (ii) the names of 11 * Sam Leffler and Silicon Graphics may not be used in any advertising or 12 * publicity relating to the software without the specific, prior written 13 * permission of Sam Leffler and Silicon Graphics. 14 * 15 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 16 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 17 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. 18 * 19 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR 20 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, 21 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 22 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 23 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 24 * OF THIS SOFTWARE. 25 */ 26 27 #include <stdio.h> 28 #include <stdlib.h> 29 #include <string.h> 30 31 #include "tiffio.h" 32 33 #define streq(a,b) (strcmp(a,b) == 0) 34 #define CopyField(tag, v) \ 35 if (TIFFGetField(in, tag, &v)) TIFFSetField(out, tag, v) 36 #define CopyField2(tag, v1, v2) \ 37 if (TIFFGetField(in, tag, &v1, &v2)) TIFFSetField(out, tag, v1, v2) 38 #define CopyField3(tag, v1, v2, v3) \ 39 if (TIFFGetField(in, tag, &v1, &v2, &v3)) TIFFSetField(out, tag, v1, v2, v3) 40 41 static char fname[1024+1]; 42 43 static int tiffcp(TIFF*, TIFF*); 44 static void newfilename(void); 45 static int cpStrips(TIFF*, TIFF*); 46 static int cpTiles(TIFF*, TIFF*); 47 48 int 49 main(int argc, char* argv[]) 50 { 51 TIFF *in, *out; 52 53 if (argc < 2) { 54 fprintf(stderr, "usage: tiffsplit input.tif [prefix]\n"); 55 return (-3); 56 } 57 if (argc > 2) 58 strcpy(fname, argv[2]); 59 in = TIFFOpen(argv[1], "r"); 60 if (in != NULL) { 61 do { 62 char path[1024+1]; 63 newfilename(); 64 strcpy(path, fname); 65 strcat(path, ".tif"); 66 out = TIFFOpen(path, "w"); 67 if (out == NULL) 68 return (-2); 69 if (!tiffcp(in, out)) 70 return (-1); 71 TIFFClose(out); 72 } while (TIFFReadDirectory(in)); 73 (void) TIFFClose(in); 74 } 75 return (0); 76 } 77 78 static void 79 newfilename(void) 80 { 81 static int first = 1; 82 static long lastTurn; 83 static long fnum; 84 static short defname; 85 static char *fpnt; 86 87 if (first) { 88 if (fname[0]) { 89 fpnt = fname + strlen(fname); 90 defname = 0; 91 } else { 92 fname[0] = 'x'; 93 fpnt = fname + 1; 94 defname = 1; 95 } 96 first = 0; 97 } 98 #define MAXFILES 17576 99 if (fnum == MAXFILES) { 100 if (!defname || fname[0] == 'z') { 101 fprintf(stderr, "tiffsplit: too many files.\n"); 102 exit(1); 103 } 104 fname[0]++; 105 fnum = 0; 106 } 107 if (fnum % 676 == 0) { 108 if (fnum != 0) { 109 //advance to next letter every 676 pages 110 //condition for 'z'++ will be covered above 111 fpnt[0]++; 112 } else { 113 //set to 'a' if we are on the very first file 114 fpnt[0] = 'a'; 115 } 116 //set the value of the last turning point 117 lastTurn = fnum; 118 } 119 //start from 0 every 676 times (provided by lastTurn) 120 //this keeps us within a-z boundaries 121 fpnt[1] = (fnum - lastTurn) / 26 + 'a'; 122 //cycle last letter every file, from a-z, then repeat 123 fpnt[2] = fnum % 26 + 'a'; 124 fnum++; 125 } 126 127 static int 128 tiffcp(TIFF* in, TIFF* out) 129 { 130 short bitspersample, samplesperpixel, shortv, *shortav; 131 uint32 w, l; 132 float floatv; 133 char *stringv; 134 uint32 longv; 135 136 CopyField(TIFFTAG_SUBFILETYPE, longv); 137 CopyField(TIFFTAG_TILEWIDTH, w); 138 CopyField(TIFFTAG_TILELENGTH, l); 139 CopyField(TIFFTAG_IMAGEWIDTH, w); 140 CopyField(TIFFTAG_IMAGELENGTH, l); 141 CopyField(TIFFTAG_BITSPERSAMPLE, bitspersample); 142 CopyField(TIFFTAG_COMPRESSION, shortv); 143 CopyField(TIFFTAG_PREDICTOR, shortv); 144 CopyField(TIFFTAG_PHOTOMETRIC, shortv); 145 CopyField(TIFFTAG_THRESHHOLDING, shortv); 146 CopyField(TIFFTAG_FILLORDER, shortv); 147 CopyField(TIFFTAG_ORIENTATION, shortv); 148 CopyField(TIFFTAG_SAMPLESPERPIXEL, samplesperpixel); 149 CopyField(TIFFTAG_MINSAMPLEVALUE, shortv); 150 CopyField(TIFFTAG_MAXSAMPLEVALUE, shortv); 151 CopyField(TIFFTAG_XRESOLUTION, floatv); 152 CopyField(TIFFTAG_YRESOLUTION, floatv); 153 CopyField(TIFFTAG_GROUP3OPTIONS, longv); 154 CopyField(TIFFTAG_GROUP4OPTIONS, longv); 155 CopyField(TIFFTAG_RESOLUTIONUNIT, shortv); 156 CopyField(TIFFTAG_PLANARCONFIG, shortv); 157 CopyField(TIFFTAG_ROWSPERSTRIP, longv); 158 CopyField(TIFFTAG_XPOSITION, floatv); 159 CopyField(TIFFTAG_YPOSITION, floatv); 160 CopyField(TIFFTAG_IMAGEDEPTH, longv); 161 CopyField(TIFFTAG_TILEDEPTH, longv); 162 CopyField(TIFFTAG_SAMPLEFORMAT, longv); 163 CopyField2(TIFFTAG_EXTRASAMPLES, shortv, shortav); 164 { uint16 *red, *green, *blue; 165 CopyField3(TIFFTAG_COLORMAP, red, green, blue); 166 } 167 { uint16 shortv2; 168 CopyField2(TIFFTAG_PAGENUMBER, shortv, shortv2); 169 } 170 CopyField(TIFFTAG_ARTIST, stringv); 171 CopyField(TIFFTAG_IMAGEDESCRIPTION, stringv); 172 CopyField(TIFFTAG_MAKE, stringv); 173 CopyField(TIFFTAG_MODEL, stringv); 174 CopyField(TIFFTAG_SOFTWARE, stringv); 175 CopyField(TIFFTAG_DATETIME, stringv); 176 CopyField(TIFFTAG_HOSTCOMPUTER, stringv); 177 CopyField(TIFFTAG_PAGENAME, stringv); 178 CopyField(TIFFTAG_DOCUMENTNAME, stringv); 179 if (TIFFIsTiled(in)) 180 return (cpTiles(in, out)); 181 else 182 return (cpStrips(in, out)); 183 } 184 185 static int 186 cpStrips(TIFF* in, TIFF* out) 187 { 188 tsize_t bufsize = TIFFStripSize(in); 189 unsigned char *buf = (unsigned char *)_TIFFmalloc(bufsize); 190 191 if (buf) { 192 tstrip_t s, ns = TIFFNumberOfStrips(in); 193 uint32 *bytecounts; 194 195 TIFFGetField(in, TIFFTAG_STRIPBYTECOUNTS, &bytecounts); 196 for (s = 0; s < ns; s++) { 197 if (bytecounts[s] > bufsize) { 198 buf = (unsigned char *)_TIFFrealloc(buf, bytecounts[s]); 199 if (!buf) 200 return (0); 201 bufsize = bytecounts[s]; 202 } 203 if (TIFFReadRawStrip(in, s, buf, bytecounts[s]) < 0 || 204 TIFFWriteRawStrip(out, s, buf, bytecounts[s]) < 0) { 205 _TIFFfree(buf); 206 return (0); 207 } 208 } 209 _TIFFfree(buf); 210 return (1); 211 } 212 return (0); 213 } 214 215 static int 216 cpTiles(TIFF* in, TIFF* out) 217 { 218 tsize_t bufsize = TIFFTileSize(in); 219 unsigned char *buf = (unsigned char *)_TIFFmalloc(bufsize); 220 221 if (buf) { 222 ttile_t t, nt = TIFFNumberOfTiles(in); 223 uint32 *bytecounts; 224 225 TIFFGetField(in, TIFFTAG_TILEBYTECOUNTS, &bytecounts); 226 for (t = 0; t < nt; t++) { 227 if (bytecounts[t] > bufsize) { 228 buf = (unsigned char *)_TIFFrealloc(buf, bytecounts[t]); 229 if (!buf) 230 return (0); 231 bufsize = bytecounts[t]; 232 } 233 if (TIFFReadRawTile(in, t, buf, bytecounts[t]) < 0 || 234 TIFFWriteRawTile(out, t, buf, bytecounts[t]) < 0) { 235 _TIFFfree(buf); 236 return (0); 237 } 238 } 239 _TIFFfree(buf); 240 return (1); 241 } 242 return (0); 243 } 244