1 /* $Id: tiffsplit.c,v 1.9 2004-06-05 08:11:26 dron 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 CopyField(tag, v) \ 34 if (TIFFGetField(in, tag, &v)) TIFFSetField(out, tag, v) 35 #define CopyField2(tag, v1, v2) \ 36 if (TIFFGetField(in, tag, &v1, &v2)) TIFFSetField(out, tag, v1, v2) 37 #define CopyField3(tag, v1, v2, v3) \ 38 if (TIFFGetField(in, tag, &v1, &v2, &v3)) TIFFSetField(out, tag, v1, v2, v3) 39 40 static char fname[1024+1]; 41 42 static int tiffcp(TIFF*, TIFF*); 43 static void newfilename(void); 44 static int cpStrips(TIFF*, TIFF*); 45 static int cpTiles(TIFF*, TIFF*); 46 47 int 48 main(int argc, char* argv[]) 49 { 50 TIFF *in, *out; 51 52 if (argc < 2) { 53 fprintf(stderr, "usage: tiffsplit input.tif [prefix]\n"); 54 return (-3); 55 } 56 if (argc > 2) 57 strcpy(fname, argv[2]); 58 in = TIFFOpen(argv[1], "r"); 59 if (in != NULL) { 60 do { 61 char path[1024+1]; 62 newfilename(); 63 strcpy(path, fname); 64 strcat(path, ".tif"); 65 out = TIFFOpen(path, TIFFIsBigEndian(in)?"wb":"wl"); 66 if (out == NULL) 67 return (-2); 68 if (!tiffcp(in, out)) 69 return (-1); 70 TIFFClose(out); 71 } while (TIFFReadDirectory(in)); 72 (void) TIFFClose(in); 73 } 74 return (0); 75 } 76 77 static void 78 newfilename(void) 79 { 80 static int first = 1; 81 static long lastTurn; 82 static long fnum; 83 static short defname; 84 static char *fpnt; 85 86 if (first) { 87 if (fname[0]) { 88 fpnt = fname + strlen(fname); 89 defname = 0; 90 } else { 91 fname[0] = 'x'; 92 fpnt = fname + 1; 93 defname = 1; 94 } 95 first = 0; 96 } 97 #define MAXFILES 17576 98 if (fnum == MAXFILES) { 99 if (!defname || fname[0] == 'z') { 100 fprintf(stderr, "tiffsplit: too many files.\n"); 101 exit(1); 102 } 103 fname[0]++; 104 fnum = 0; 105 } 106 if (fnum % 676 == 0) { 107 if (fnum != 0) { 108 /* 109 * advance to next letter every 676 pages 110 * condition for 'z'++ will be covered above 111 */ 112 fpnt[0]++; 113 } else { 114 /* 115 * set to 'a' if we are on the very first file 116 */ 117 fpnt[0] = 'a'; 118 } 119 /* 120 * set the value of the last turning point 121 */ 122 lastTurn = fnum; 123 } 124 /* 125 * start from 0 every 676 times (provided by lastTurn) 126 * this keeps us within a-z boundaries 127 */ 128 fpnt[1] = (fnum - lastTurn) / 26 + 'a'; 129 /* 130 * cycle last letter every file, from a-z, then repeat 131 */ 132 fpnt[2] = fnum % 26 + 'a'; 133 fnum++; 134 } 135 136 static int 137 tiffcp(TIFF* in, TIFF* out) 138 { 139 uint16 bitspersample, samplesperpixel, compression, shortv, *shortav; 140 uint32 w, l; 141 float floatv; 142 char *stringv; 143 uint32 longv; 144 145 CopyField(TIFFTAG_SUBFILETYPE, longv); 146 CopyField(TIFFTAG_TILEWIDTH, w); 147 CopyField(TIFFTAG_TILELENGTH, l); 148 CopyField(TIFFTAG_IMAGEWIDTH, w); 149 CopyField(TIFFTAG_IMAGELENGTH, l); 150 CopyField(TIFFTAG_BITSPERSAMPLE, bitspersample); 151 CopyField(TIFFTAG_SAMPLESPERPIXEL, samplesperpixel); 152 CopyField(TIFFTAG_COMPRESSION, compression); 153 if (compression == COMPRESSION_JPEG) { 154 uint16 count; 155 void *table; 156 TIFFGetField(in, TIFFTAG_JPEGTABLES, &count, &table); 157 TIFFSetField(out, TIFFTAG_JPEGTABLES, count, table); 158 } 159 CopyField(TIFFTAG_PHOTOMETRIC, shortv); 160 CopyField(TIFFTAG_PREDICTOR, shortv); 161 CopyField(TIFFTAG_THRESHHOLDING, shortv); 162 CopyField(TIFFTAG_FILLORDER, shortv); 163 CopyField(TIFFTAG_ORIENTATION, shortv); 164 CopyField(TIFFTAG_MINSAMPLEVALUE, shortv); 165 CopyField(TIFFTAG_MAXSAMPLEVALUE, shortv); 166 CopyField(TIFFTAG_XRESOLUTION, floatv); 167 CopyField(TIFFTAG_YRESOLUTION, floatv); 168 CopyField(TIFFTAG_GROUP3OPTIONS, longv); 169 CopyField(TIFFTAG_GROUP4OPTIONS, longv); 170 CopyField(TIFFTAG_RESOLUTIONUNIT, shortv); 171 CopyField(TIFFTAG_PLANARCONFIG, shortv); 172 CopyField(TIFFTAG_ROWSPERSTRIP, longv); 173 CopyField(TIFFTAG_XPOSITION, floatv); 174 CopyField(TIFFTAG_YPOSITION, floatv); 175 CopyField(TIFFTAG_IMAGEDEPTH, longv); 176 CopyField(TIFFTAG_TILEDEPTH, longv); 177 CopyField(TIFFTAG_SAMPLEFORMAT, longv); 178 CopyField2(TIFFTAG_EXTRASAMPLES, shortv, shortav); 179 { uint16 *red, *green, *blue; 180 CopyField3(TIFFTAG_COLORMAP, red, green, blue); 181 } 182 { uint16 shortv2; 183 CopyField2(TIFFTAG_PAGENUMBER, shortv, shortv2); 184 } 185 CopyField(TIFFTAG_ARTIST, stringv); 186 CopyField(TIFFTAG_IMAGEDESCRIPTION, stringv); 187 CopyField(TIFFTAG_MAKE, stringv); 188 CopyField(TIFFTAG_MODEL, stringv); 189 CopyField(TIFFTAG_SOFTWARE, stringv); 190 CopyField(TIFFTAG_DATETIME, stringv); 191 CopyField(TIFFTAG_HOSTCOMPUTER, stringv); 192 CopyField(TIFFTAG_PAGENAME, stringv); 193 CopyField(TIFFTAG_DOCUMENTNAME, stringv); 194 if (TIFFIsTiled(in)) 195 return (cpTiles(in, out)); 196 else 197 return (cpStrips(in, out)); 198 } 199 200 static int 201 cpStrips(TIFF* in, TIFF* out) 202 { 203 tsize_t bufsize = TIFFStripSize(in); 204 unsigned char *buf = (unsigned char *)_TIFFmalloc(bufsize); 205 206 if (buf) { 207 tstrip_t s, ns = TIFFNumberOfStrips(in); 208 uint32 *bytecounts; 209 210 TIFFGetField(in, TIFFTAG_STRIPBYTECOUNTS, &bytecounts); 211 for (s = 0; s < ns; s++) { 212 if (bytecounts[s] > (uint32)bufsize) { 213 buf = (unsigned char *)_TIFFrealloc(buf, bytecounts[s]); 214 if (!buf) 215 return (0); 216 bufsize = bytecounts[s]; 217 } 218 if (TIFFReadRawStrip(in, s, buf, bytecounts[s]) < 0 || 219 TIFFWriteRawStrip(out, s, buf, bytecounts[s]) < 0) { 220 _TIFFfree(buf); 221 return (0); 222 } 223 } 224 _TIFFfree(buf); 225 return (1); 226 } 227 return (0); 228 } 229 230 static int 231 cpTiles(TIFF* in, TIFF* out) 232 { 233 tsize_t bufsize = TIFFTileSize(in); 234 unsigned char *buf = (unsigned char *)_TIFFmalloc(bufsize); 235 236 if (buf) { 237 ttile_t t, nt = TIFFNumberOfTiles(in); 238 uint32 *bytecounts; 239 240 TIFFGetField(in, TIFFTAG_TILEBYTECOUNTS, &bytecounts); 241 for (t = 0; t < nt; t++) { 242 if (bytecounts[t] > (uint32) bufsize) { 243 buf = (unsigned char *)_TIFFrealloc(buf, bytecounts[t]); 244 if (!buf) 245 return (0); 246 bufsize = bytecounts[t]; 247 } 248 if (TIFFReadRawTile(in, t, buf, bytecounts[t]) < 0 || 249 TIFFWriteRawTile(out, t, buf, bytecounts[t]) < 0) { 250 _TIFFfree(buf); 251 return (0); 252 } 253 } 254 _TIFFfree(buf); 255 return (1); 256 } 257 return (0); 258 } 259