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