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