1/* $Id: tif_write.c,v 1.42 2015-06-07 23:00:23 bfriesen Exp $ */ 2 3/* 4 * Copyright (c) 1988-1997 Sam Leffler 5 * Copyright (c) 1991-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/* 28 * TIFF Library. 29 * 30 * Scanline-oriented Write Support 31 */ 32#include "tiffiop.h" 33#include <stdio.h> 34 35#define STRIPINCR 20 /* expansion factor on strip array */ 36 37#define WRITECHECKSTRIPS(tif, module) \ 38 (((tif)->tif_flags&TIFF_BEENWRITING) || TIFFWriteCheck((tif),0,module)) 39#define WRITECHECKTILES(tif, module) \ 40 (((tif)->tif_flags&TIFF_BEENWRITING) || TIFFWriteCheck((tif),1,module)) 41#define BUFFERCHECK(tif) \ 42 ((((tif)->tif_flags & TIFF_BUFFERSETUP) && tif->tif_rawdata) || \ 43 TIFFWriteBufferSetup((tif), NULL, (tmsize_t) -1)) 44 45static int TIFFGrowStrips(TIFF* tif, uint32 delta, const char* module); 46static int TIFFAppendToStrip(TIFF* tif, uint32 strip, uint8* data, tmsize_t cc); 47 48int 49TIFFWriteScanline(TIFF* tif, void* buf, uint32 row, uint16 sample) 50{ 51 static const char module[] = "TIFFWriteScanline"; 52 register TIFFDirectory *td; 53 int status, imagegrew = 0; 54 uint32 strip; 55 56 if (!WRITECHECKSTRIPS(tif, module)) 57 return (-1); 58 /* 59 * Handle delayed allocation of data buffer. This 60 * permits it to be sized more intelligently (using 61 * directory information). 62 */ 63 if (!BUFFERCHECK(tif)) 64 return (-1); 65 tif->tif_flags |= TIFF_BUF4WRITE; /* not strictly sure this is right*/ 66 67 td = &tif->tif_dir; 68 /* 69 * Extend image length if needed 70 * (but only for PlanarConfig=1). 71 */ 72 if (row >= td->td_imagelength) { /* extend image */ 73 if (td->td_planarconfig == PLANARCONFIG_SEPARATE) { 74 TIFFErrorExt(tif->tif_clientdata, module, 75 "Can not change \"ImageLength\" when using separate planes"); 76 return (-1); 77 } 78 td->td_imagelength = row+1; 79 imagegrew = 1; 80 } 81 /* 82 * Calculate strip and check for crossings. 83 */ 84 if (td->td_planarconfig == PLANARCONFIG_SEPARATE) { 85 if (sample >= td->td_samplesperpixel) { 86 TIFFErrorExt(tif->tif_clientdata, module, 87 "%lu: Sample out of range, max %lu", 88 (unsigned long) sample, (unsigned long) td->td_samplesperpixel); 89 return (-1); 90 } 91 strip = sample*td->td_stripsperimage + row/td->td_rowsperstrip; 92 } else 93 strip = row / td->td_rowsperstrip; 94 /* 95 * Check strip array to make sure there's space. We don't support 96 * dynamically growing files that have data organized in separate 97 * bitplanes because it's too painful. In that case we require that 98 * the imagelength be set properly before the first write (so that the 99 * strips array will be fully allocated above). 100 */ 101 if (strip >= td->td_nstrips && !TIFFGrowStrips(tif, 1, module)) 102 return (-1); 103 if (strip != tif->tif_curstrip) { 104 /* 105 * Changing strips -- flush any data present. 106 */ 107 if (!TIFFFlushData(tif)) 108 return (-1); 109 tif->tif_curstrip = strip; 110 /* 111 * Watch out for a growing image. The value of strips/image 112 * will initially be 1 (since it can't be deduced until the 113 * imagelength is known). 114 */ 115 if (strip >= td->td_stripsperimage && imagegrew) 116 td->td_stripsperimage = 117 TIFFhowmany_32(td->td_imagelength,td->td_rowsperstrip); 118 if (td->td_stripsperimage == 0) { 119 TIFFErrorExt(tif->tif_clientdata, module, "Zero strips per image"); 120 return (-1); 121 } 122 tif->tif_row = 123 (strip % td->td_stripsperimage) * td->td_rowsperstrip; 124 if ((tif->tif_flags & TIFF_CODERSETUP) == 0) { 125 if (!(*tif->tif_setupencode)(tif)) 126 return (-1); 127 tif->tif_flags |= TIFF_CODERSETUP; 128 } 129 130 tif->tif_rawcc = 0; 131 tif->tif_rawcp = tif->tif_rawdata; 132 133 if( td->td_stripbytecount[strip] > 0 ) 134 { 135 /* if we are writing over existing tiles, zero length */ 136 td->td_stripbytecount[strip] = 0; 137 138 /* this forces TIFFAppendToStrip() to do a seek */ 139 tif->tif_curoff = 0; 140 } 141 142 if (!(*tif->tif_preencode)(tif, sample)) 143 return (-1); 144 tif->tif_flags |= TIFF_POSTENCODE; 145 } 146 /* 147 * Ensure the write is either sequential or at the 148 * beginning of a strip (or that we can randomly 149 * access the data -- i.e. no encoding). 150 */ 151 if (row != tif->tif_row) { 152 if (row < tif->tif_row) { 153 /* 154 * Moving backwards within the same strip: 155 * backup to the start and then decode 156 * forward (below). 157 */ 158 tif->tif_row = (strip % td->td_stripsperimage) * 159 td->td_rowsperstrip; 160 tif->tif_rawcp = tif->tif_rawdata; 161 } 162 /* 163 * Seek forward to the desired row. 164 */ 165 if (!(*tif->tif_seek)(tif, row - tif->tif_row)) 166 return (-1); 167 tif->tif_row = row; 168 } 169 170 /* swab if needed - note that source buffer will be altered */ 171 tif->tif_postdecode( tif, (uint8*) buf, tif->tif_scanlinesize ); 172 173 status = (*tif->tif_encoderow)(tif, (uint8*) buf, 174 tif->tif_scanlinesize, sample); 175 176 /* we are now poised at the beginning of the next row */ 177 tif->tif_row = row + 1; 178 return (status); 179} 180 181/* 182 * Encode the supplied data and write it to the 183 * specified strip. 184 * 185 * NB: Image length must be setup before writing. 186 */ 187tmsize_t 188TIFFWriteEncodedStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc) 189{ 190 static const char module[] = "TIFFWriteEncodedStrip"; 191 TIFFDirectory *td = &tif->tif_dir; 192 uint16 sample; 193 194 if (!WRITECHECKSTRIPS(tif, module)) 195 return ((tmsize_t) -1); 196 /* 197 * Check strip array to make sure there's space. 198 * We don't support dynamically growing files that 199 * have data organized in separate bitplanes because 200 * it's too painful. In that case we require that 201 * the imagelength be set properly before the first 202 * write (so that the strips array will be fully 203 * allocated above). 204 */ 205 if (strip >= td->td_nstrips) { 206 if (td->td_planarconfig == PLANARCONFIG_SEPARATE) { 207 TIFFErrorExt(tif->tif_clientdata, module, 208 "Can not grow image by strips when using separate planes"); 209 return ((tmsize_t) -1); 210 } 211 if (!TIFFGrowStrips(tif, 1, module)) 212 return ((tmsize_t) -1); 213 td->td_stripsperimage = 214 TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip); 215 } 216 /* 217 * Handle delayed allocation of data buffer. This 218 * permits it to be sized according to the directory 219 * info. 220 */ 221 if (!BUFFERCHECK(tif)) 222 return ((tmsize_t) -1); 223 224 tif->tif_flags |= TIFF_BUF4WRITE; 225 tif->tif_curstrip = strip; 226 227 if (td->td_stripsperimage == 0) { 228 TIFFErrorExt(tif->tif_clientdata, module, "Zero strips per image"); 229 return ((tmsize_t) -1); 230 } 231 232 tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip; 233 if ((tif->tif_flags & TIFF_CODERSETUP) == 0) { 234 if (!(*tif->tif_setupencode)(tif)) 235 return ((tmsize_t) -1); 236 tif->tif_flags |= TIFF_CODERSETUP; 237 } 238 239 if( td->td_stripbytecount[strip] > 0 ) 240 { 241 /* Make sure that at the first attempt of rewriting the tile, we will have */ 242 /* more bytes available in the output buffer than the previous byte count, */ 243 /* so that TIFFAppendToStrip() will detect the overflow when it is called the first */ 244 /* time if the new compressed tile is bigger than the older one. (GDAL #4771) */ 245 if( tif->tif_rawdatasize <= (tmsize_t)td->td_stripbytecount[strip] ) 246 { 247 if( !(TIFFWriteBufferSetup(tif, NULL, 248 (tmsize_t)TIFFroundup_64((uint64)(td->td_stripbytecount[strip] + 1), 1024))) ) 249 return ((tmsize_t)(-1)); 250 } 251 252 /* Force TIFFAppendToStrip() to consider placing data at end 253 of file. */ 254 tif->tif_curoff = 0; 255 } 256 257 tif->tif_rawcc = 0; 258 tif->tif_rawcp = tif->tif_rawdata; 259 260 tif->tif_flags &= ~TIFF_POSTENCODE; 261 sample = (uint16)(strip / td->td_stripsperimage); 262 if (!(*tif->tif_preencode)(tif, sample)) 263 return ((tmsize_t) -1); 264 265 /* swab if needed - note that source buffer will be altered */ 266 tif->tif_postdecode( tif, (uint8*) data, cc ); 267 268 if (!(*tif->tif_encodestrip)(tif, (uint8*) data, cc, sample)) 269 return (0); 270 if (!(*tif->tif_postencode)(tif)) 271 return ((tmsize_t) -1); 272 if (!isFillOrder(tif, td->td_fillorder) && 273 (tif->tif_flags & TIFF_NOBITREV) == 0) 274 TIFFReverseBits(tif->tif_rawdata, tif->tif_rawcc); 275 if (tif->tif_rawcc > 0 && 276 !TIFFAppendToStrip(tif, strip, tif->tif_rawdata, tif->tif_rawcc)) 277 return ((tmsize_t) -1); 278 tif->tif_rawcc = 0; 279 tif->tif_rawcp = tif->tif_rawdata; 280 return (cc); 281} 282 283/* 284 * Write the supplied data to the specified strip. 285 * 286 * NB: Image length must be setup before writing. 287 */ 288tmsize_t 289TIFFWriteRawStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc) 290{ 291 static const char module[] = "TIFFWriteRawStrip"; 292 TIFFDirectory *td = &tif->tif_dir; 293 294 if (!WRITECHECKSTRIPS(tif, module)) 295 return ((tmsize_t) -1); 296 /* 297 * Check strip array to make sure there's space. 298 * We don't support dynamically growing files that 299 * have data organized in separate bitplanes because 300 * it's too painful. In that case we require that 301 * the imagelength be set properly before the first 302 * write (so that the strips array will be fully 303 * allocated above). 304 */ 305 if (strip >= td->td_nstrips) { 306 if (td->td_planarconfig == PLANARCONFIG_SEPARATE) { 307 TIFFErrorExt(tif->tif_clientdata, module, 308 "Can not grow image by strips when using separate planes"); 309 return ((tmsize_t) -1); 310 } 311 /* 312 * Watch out for a growing image. The value of 313 * strips/image will initially be 1 (since it 314 * can't be deduced until the imagelength is known). 315 */ 316 if (strip >= td->td_stripsperimage) 317 td->td_stripsperimage = 318 TIFFhowmany_32(td->td_imagelength,td->td_rowsperstrip); 319 if (!TIFFGrowStrips(tif, 1, module)) 320 return ((tmsize_t) -1); 321 } 322 tif->tif_curstrip = strip; 323 if (td->td_stripsperimage == 0) { 324 TIFFErrorExt(tif->tif_clientdata, module,"Zero strips per image"); 325 return ((tmsize_t) -1); 326 } 327 tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip; 328 return (TIFFAppendToStrip(tif, strip, (uint8*) data, cc) ? 329 cc : (tmsize_t) -1); 330} 331 332/* 333 * Write and compress a tile of data. The 334 * tile is selected by the (x,y,z,s) coordinates. 335 */ 336tmsize_t 337TIFFWriteTile(TIFF* tif, void* buf, uint32 x, uint32 y, uint32 z, uint16 s) 338{ 339 if (!TIFFCheckTile(tif, x, y, z, s)) 340 return ((tmsize_t)(-1)); 341 /* 342 * NB: A tile size of -1 is used instead of tif_tilesize knowing 343 * that TIFFWriteEncodedTile will clamp this to the tile size. 344 * This is done because the tile size may not be defined until 345 * after the output buffer is setup in TIFFWriteBufferSetup. 346 */ 347 return (TIFFWriteEncodedTile(tif, 348 TIFFComputeTile(tif, x, y, z, s), buf, (tmsize_t)(-1))); 349} 350 351/* 352 * Encode the supplied data and write it to the 353 * specified tile. There must be space for the 354 * data. The function clamps individual writes 355 * to a tile to the tile size, but does not (and 356 * can not) check that multiple writes to the same 357 * tile do not write more than tile size data. 358 * 359 * NB: Image length must be setup before writing; this 360 * interface does not support automatically growing 361 * the image on each write (as TIFFWriteScanline does). 362 */ 363tmsize_t 364TIFFWriteEncodedTile(TIFF* tif, uint32 tile, void* data, tmsize_t cc) 365{ 366 static const char module[] = "TIFFWriteEncodedTile"; 367 TIFFDirectory *td; 368 uint16 sample; 369 uint32 howmany32; 370 371 if (!WRITECHECKTILES(tif, module)) 372 return ((tmsize_t)(-1)); 373 td = &tif->tif_dir; 374 if (tile >= td->td_nstrips) { 375 TIFFErrorExt(tif->tif_clientdata, module, "Tile %lu out of range, max %lu", 376 (unsigned long) tile, (unsigned long) td->td_nstrips); 377 return ((tmsize_t)(-1)); 378 } 379 /* 380 * Handle delayed allocation of data buffer. This 381 * permits it to be sized more intelligently (using 382 * directory information). 383 */ 384 if (!BUFFERCHECK(tif)) 385 return ((tmsize_t)(-1)); 386 387 tif->tif_flags |= TIFF_BUF4WRITE; 388 tif->tif_curtile = tile; 389 390 if( td->td_stripbytecount[tile] > 0 ) 391 { 392 /* Make sure that at the first attempt of rewriting the tile, we will have */ 393 /* more bytes available in the output buffer than the previous byte count, */ 394 /* so that TIFFAppendToStrip() will detect the overflow when it is called the first */ 395 /* time if the new compressed tile is bigger than the older one. (GDAL #4771) */ 396 if( tif->tif_rawdatasize <= (tmsize_t) td->td_stripbytecount[tile] ) 397 { 398 if( !(TIFFWriteBufferSetup(tif, NULL, 399 (tmsize_t)TIFFroundup_64((uint64)(td->td_stripbytecount[tile] + 1), 1024))) ) 400 return ((tmsize_t)(-1)); 401 } 402 403 /* Force TIFFAppendToStrip() to consider placing data at end 404 of file. */ 405 tif->tif_curoff = 0; 406 } 407 408 tif->tif_rawcc = 0; 409 tif->tif_rawcp = tif->tif_rawdata; 410 411 /* 412 * Compute tiles per row & per column to compute 413 * current row and column 414 */ 415 howmany32=TIFFhowmany_32(td->td_imagelength, td->td_tilelength); 416 if (howmany32 == 0) { 417 TIFFErrorExt(tif->tif_clientdata,module,"Zero tiles"); 418 return ((tmsize_t)(-1)); 419 } 420 tif->tif_row = (tile % howmany32) * td->td_tilelength; 421 howmany32=TIFFhowmany_32(td->td_imagewidth, td->td_tilewidth); 422 if (howmany32 == 0) { 423 TIFFErrorExt(tif->tif_clientdata,module,"Zero tiles"); 424 return ((tmsize_t)(-1)); 425 } 426 tif->tif_col = (tile % howmany32) * td->td_tilewidth; 427 428 if ((tif->tif_flags & TIFF_CODERSETUP) == 0) { 429 if (!(*tif->tif_setupencode)(tif)) 430 return ((tmsize_t)(-1)); 431 tif->tif_flags |= TIFF_CODERSETUP; 432 } 433 tif->tif_flags &= ~TIFF_POSTENCODE; 434 sample = (uint16)(tile/td->td_stripsperimage); 435 if (!(*tif->tif_preencode)(tif, sample)) 436 return ((tmsize_t)(-1)); 437 /* 438 * Clamp write amount to the tile size. This is mostly 439 * done so that callers can pass in some large number 440 * (e.g. -1) and have the tile size used instead. 441 */ 442 if ( cc < 1 || cc > tif->tif_tilesize) 443 cc = tif->tif_tilesize; 444 445 /* swab if needed - note that source buffer will be altered */ 446 tif->tif_postdecode( tif, (uint8*) data, cc ); 447 448 if (!(*tif->tif_encodetile)(tif, (uint8*) data, cc, sample)) 449 return (0); 450 if (!(*tif->tif_postencode)(tif)) 451 return ((tmsize_t)(-1)); 452 if (!isFillOrder(tif, td->td_fillorder) && 453 (tif->tif_flags & TIFF_NOBITREV) == 0) 454 TIFFReverseBits((uint8*)tif->tif_rawdata, tif->tif_rawcc); 455 if (tif->tif_rawcc > 0 && !TIFFAppendToStrip(tif, tile, 456 tif->tif_rawdata, tif->tif_rawcc)) 457 return ((tmsize_t)(-1)); 458 tif->tif_rawcc = 0; 459 tif->tif_rawcp = tif->tif_rawdata; 460 return (cc); 461} 462 463/* 464 * Write the supplied data to the specified strip. 465 * There must be space for the data; we don't check 466 * if strips overlap! 467 * 468 * NB: Image length must be setup before writing; this 469 * interface does not support automatically growing 470 * the image on each write (as TIFFWriteScanline does). 471 */ 472tmsize_t 473TIFFWriteRawTile(TIFF* tif, uint32 tile, void* data, tmsize_t cc) 474{ 475 static const char module[] = "TIFFWriteRawTile"; 476 477 if (!WRITECHECKTILES(tif, module)) 478 return ((tmsize_t)(-1)); 479 if (tile >= tif->tif_dir.td_nstrips) { 480 TIFFErrorExt(tif->tif_clientdata, module, "Tile %lu out of range, max %lu", 481 (unsigned long) tile, 482 (unsigned long) tif->tif_dir.td_nstrips); 483 return ((tmsize_t)(-1)); 484 } 485 return (TIFFAppendToStrip(tif, tile, (uint8*) data, cc) ? 486 cc : (tmsize_t)(-1)); 487} 488 489#define isUnspecified(tif, f) \ 490 (TIFFFieldSet(tif,f) && (tif)->tif_dir.td_imagelength == 0) 491 492int 493TIFFSetupStrips(TIFF* tif) 494{ 495 TIFFDirectory* td = &tif->tif_dir; 496 497 if (isTiled(tif)) 498 td->td_stripsperimage = 499 isUnspecified(tif, FIELD_TILEDIMENSIONS) ? 500 td->td_samplesperpixel : TIFFNumberOfTiles(tif); 501 else 502 td->td_stripsperimage = 503 isUnspecified(tif, FIELD_ROWSPERSTRIP) ? 504 td->td_samplesperpixel : TIFFNumberOfStrips(tif); 505 td->td_nstrips = td->td_stripsperimage; 506 if (td->td_planarconfig == PLANARCONFIG_SEPARATE) 507 td->td_stripsperimage /= td->td_samplesperpixel; 508 td->td_stripoffset = (uint64 *) 509 _TIFFmalloc(td->td_nstrips * sizeof (uint64)); 510 td->td_stripbytecount = (uint64 *) 511 _TIFFmalloc(td->td_nstrips * sizeof (uint64)); 512 if (td->td_stripoffset == NULL || td->td_stripbytecount == NULL) 513 return (0); 514 /* 515 * Place data at the end-of-file 516 * (by setting offsets to zero). 517 */ 518 _TIFFmemset(td->td_stripoffset, 0, td->td_nstrips*sizeof (uint64)); 519 _TIFFmemset(td->td_stripbytecount, 0, td->td_nstrips*sizeof (uint64)); 520 TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS); 521 TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS); 522 return (1); 523} 524#undef isUnspecified 525 526/* 527 * Verify file is writable and that the directory 528 * information is setup properly. In doing the latter 529 * we also "freeze" the state of the directory so 530 * that important information is not changed. 531 */ 532int 533TIFFWriteCheck(TIFF* tif, int tiles, const char* module) 534{ 535 if (tif->tif_mode == O_RDONLY) { 536 TIFFErrorExt(tif->tif_clientdata, module, "File not open for writing"); 537 return (0); 538 } 539 if (tiles ^ isTiled(tif)) { 540 TIFFErrorExt(tif->tif_clientdata, module, tiles ? 541 "Can not write tiles to a stripped image" : 542 "Can not write scanlines to a tiled image"); 543 return (0); 544 } 545 546 _TIFFFillStriles( tif ); 547 548 /* 549 * On the first write verify all the required information 550 * has been setup and initialize any data structures that 551 * had to wait until directory information was set. 552 * Note that a lot of our work is assumed to remain valid 553 * because we disallow any of the important parameters 554 * from changing after we start writing (i.e. once 555 * TIFF_BEENWRITING is set, TIFFSetField will only allow 556 * the image's length to be changed). 557 */ 558 if (!TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS)) { 559 TIFFErrorExt(tif->tif_clientdata, module, 560 "Must set \"ImageWidth\" before writing data"); 561 return (0); 562 } 563 if (tif->tif_dir.td_samplesperpixel == 1) { 564 /* 565 * Planarconfiguration is irrelevant in case of single band 566 * images and need not be included. We will set it anyway, 567 * because this field is used in other parts of library even 568 * in the single band case. 569 */ 570 if (!TIFFFieldSet(tif, FIELD_PLANARCONFIG)) 571 tif->tif_dir.td_planarconfig = PLANARCONFIG_CONTIG; 572 } else { 573 if (!TIFFFieldSet(tif, FIELD_PLANARCONFIG)) { 574 TIFFErrorExt(tif->tif_clientdata, module, 575 "Must set \"PlanarConfiguration\" before writing data"); 576 return (0); 577 } 578 } 579 if (tif->tif_dir.td_stripoffset == NULL && !TIFFSetupStrips(tif)) { 580 tif->tif_dir.td_nstrips = 0; 581 TIFFErrorExt(tif->tif_clientdata, module, "No space for %s arrays", 582 isTiled(tif) ? "tile" : "strip"); 583 return (0); 584 } 585 if (isTiled(tif)) 586 { 587 tif->tif_tilesize = TIFFTileSize(tif); 588 if (tif->tif_tilesize == 0) 589 return (0); 590 } 591 else 592 tif->tif_tilesize = (tmsize_t)(-1); 593 tif->tif_scanlinesize = TIFFScanlineSize(tif); 594 if (tif->tif_scanlinesize == 0) 595 return (0); 596 tif->tif_flags |= TIFF_BEENWRITING; 597 return (1); 598} 599 600/* 601 * Setup the raw data buffer used for encoding. 602 */ 603int 604TIFFWriteBufferSetup(TIFF* tif, void* bp, tmsize_t size) 605{ 606 static const char module[] = "TIFFWriteBufferSetup"; 607 608 if (tif->tif_rawdata) { 609 if (tif->tif_flags & TIFF_MYBUFFER) { 610 _TIFFfree(tif->tif_rawdata); 611 tif->tif_flags &= ~TIFF_MYBUFFER; 612 } 613 tif->tif_rawdata = NULL; 614 } 615 if (size == (tmsize_t)(-1)) { 616 size = (isTiled(tif) ? 617 tif->tif_tilesize : TIFFStripSize(tif)); 618 /* 619 * Make raw data buffer at least 8K 620 */ 621 if (size < 8*1024) 622 size = 8*1024; 623 bp = NULL; /* NB: force malloc */ 624 } 625 if (bp == NULL) { 626 bp = _TIFFmalloc(size); 627 if (bp == NULL) { 628 TIFFErrorExt(tif->tif_clientdata, module, "No space for output buffer"); 629 return (0); 630 } 631 tif->tif_flags |= TIFF_MYBUFFER; 632 } else 633 tif->tif_flags &= ~TIFF_MYBUFFER; 634 tif->tif_rawdata = (uint8*) bp; 635 tif->tif_rawdatasize = size; 636 tif->tif_rawcc = 0; 637 tif->tif_rawcp = tif->tif_rawdata; 638 tif->tif_flags |= TIFF_BUFFERSETUP; 639 return (1); 640} 641 642/* 643 * Grow the strip data structures by delta strips. 644 */ 645static int 646TIFFGrowStrips(TIFF* tif, uint32 delta, const char* module) 647{ 648 TIFFDirectory *td = &tif->tif_dir; 649 uint64* new_stripoffset; 650 uint64* new_stripbytecount; 651 652 assert(td->td_planarconfig == PLANARCONFIG_CONTIG); 653 new_stripoffset = (uint64*)_TIFFrealloc(td->td_stripoffset, 654 (td->td_nstrips + delta) * sizeof (uint64)); 655 new_stripbytecount = (uint64*)_TIFFrealloc(td->td_stripbytecount, 656 (td->td_nstrips + delta) * sizeof (uint64)); 657 if (new_stripoffset == NULL || new_stripbytecount == NULL) { 658 if (new_stripoffset) 659 _TIFFfree(new_stripoffset); 660 if (new_stripbytecount) 661 _TIFFfree(new_stripbytecount); 662 td->td_nstrips = 0; 663 TIFFErrorExt(tif->tif_clientdata, module, "No space to expand strip arrays"); 664 return (0); 665 } 666 td->td_stripoffset = new_stripoffset; 667 td->td_stripbytecount = new_stripbytecount; 668 _TIFFmemset(td->td_stripoffset + td->td_nstrips, 669 0, delta*sizeof (uint64)); 670 _TIFFmemset(td->td_stripbytecount + td->td_nstrips, 671 0, delta*sizeof (uint64)); 672 td->td_nstrips += delta; 673 tif->tif_flags |= TIFF_DIRTYDIRECT; 674 675 return (1); 676} 677 678/* 679 * Append the data to the specified strip. 680 */ 681static int 682TIFFAppendToStrip(TIFF* tif, uint32 strip, uint8* data, tmsize_t cc) 683{ 684 static const char module[] = "TIFFAppendToStrip"; 685 TIFFDirectory *td = &tif->tif_dir; 686 uint64 m; 687 int64 old_byte_count = -1; 688 689 if (td->td_stripoffset[strip] == 0 || tif->tif_curoff == 0) { 690 assert(td->td_nstrips > 0); 691 692 if( td->td_stripbytecount[strip] != 0 693 && td->td_stripoffset[strip] != 0 694 && td->td_stripbytecount[strip] >= (uint64) cc ) 695 { 696 /* 697 * There is already tile data on disk, and the new tile 698 * data we have will fit in the same space. The only 699 * aspect of this that is risky is that there could be 700 * more data to append to this strip before we are done 701 * depending on how we are getting called. 702 */ 703 if (!SeekOK(tif, td->td_stripoffset[strip])) { 704 TIFFErrorExt(tif->tif_clientdata, module, 705 "Seek error at scanline %lu", 706 (unsigned long)tif->tif_row); 707 return (0); 708 } 709 } 710 else 711 { 712 /* 713 * Seek to end of file, and set that as our location to 714 * write this strip. 715 */ 716 td->td_stripoffset[strip] = TIFFSeekFile(tif, 0, SEEK_END); 717 tif->tif_flags |= TIFF_DIRTYSTRIP; 718 } 719 720 tif->tif_curoff = td->td_stripoffset[strip]; 721 722 /* 723 * We are starting a fresh strip/tile, so set the size to zero. 724 */ 725 old_byte_count = td->td_stripbytecount[strip]; 726 td->td_stripbytecount[strip] = 0; 727 } 728 729 m = tif->tif_curoff+cc; 730 if (!(tif->tif_flags&TIFF_BIGTIFF)) 731 m = (uint32)m; 732 if ((m<tif->tif_curoff)||(m<(uint64)cc)) 733 { 734 TIFFErrorExt(tif->tif_clientdata, module, "Maximum TIFF file size exceeded"); 735 return (0); 736 } 737 if (!WriteOK(tif, data, cc)) { 738 TIFFErrorExt(tif->tif_clientdata, module, "Write error at scanline %lu", 739 (unsigned long) tif->tif_row); 740 return (0); 741 } 742 tif->tif_curoff = m; 743 td->td_stripbytecount[strip] += cc; 744 745 if( (int64) td->td_stripbytecount[strip] != old_byte_count ) 746 tif->tif_flags |= TIFF_DIRTYSTRIP; 747 748 return (1); 749} 750 751/* 752 * Internal version of TIFFFlushData that can be 753 * called by ``encodestrip routines'' w/o concern 754 * for infinite recursion. 755 */ 756int 757TIFFFlushData1(TIFF* tif) 758{ 759 if (tif->tif_rawcc > 0 && tif->tif_flags & TIFF_BUF4WRITE ) { 760 if (!isFillOrder(tif, tif->tif_dir.td_fillorder) && 761 (tif->tif_flags & TIFF_NOBITREV) == 0) 762 TIFFReverseBits((uint8*)tif->tif_rawdata, 763 tif->tif_rawcc); 764 if (!TIFFAppendToStrip(tif, 765 isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip, 766 tif->tif_rawdata, tif->tif_rawcc)) 767 return (0); 768 tif->tif_rawcc = 0; 769 tif->tif_rawcp = tif->tif_rawdata; 770 } 771 return (1); 772} 773 774/* 775 * Set the current write offset. This should only be 776 * used to set the offset to a known previous location 777 * (very carefully), or to 0 so that the next write gets 778 * appended to the end of the file. 779 */ 780void 781TIFFSetWriteOffset(TIFF* tif, toff_t off) 782{ 783 tif->tif_curoff = off; 784} 785 786/* vim: set ts=8 sts=8 sw=8 noet: */ 787/* 788 * Local Variables: 789 * mode: c 790 * c-basic-offset: 8 791 * fill-column: 78 792 * End: 793 */ 794