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 31 #include <precomp.h> 32 //#include <stdio.h> 33 34 #define STRIPINCR 20 /* expansion factor on strip array */ 35 36 #define WRITECHECKSTRIPS(tif, module) \ 37 (((tif)->tif_flags&TIFF_BEENWRITING) || TIFFWriteCheck((tif),0,module)) 38 #define WRITECHECKTILES(tif, module) \ 39 (((tif)->tif_flags&TIFF_BEENWRITING) || TIFFWriteCheck((tif),1,module)) 40 #define BUFFERCHECK(tif) \ 41 ((((tif)->tif_flags & TIFF_BUFFERSETUP) && tif->tif_rawdata) || \ 42 TIFFWriteBufferSetup((tif), NULL, (tmsize_t) -1)) 43 44 static int TIFFGrowStrips(TIFF* tif, uint32 delta, const char* module); 45 static int TIFFAppendToStrip(TIFF* tif, uint32 strip, uint8* data, tmsize_t cc); 46 47 int 48 TIFFWriteScanline(TIFF* tif, void* buf, uint32 row, uint16 sample) 49 { 50 static const char module[] = "TIFFWriteScanline"; 51 register TIFFDirectory *td; 52 int status, imagegrew = 0; 53 uint32 strip; 54 55 if (!WRITECHECKSTRIPS(tif, module)) 56 return (-1); 57 /* 58 * Handle delayed allocation of data buffer. This 59 * permits it to be sized more intelligently (using 60 * directory information). 61 */ 62 if (!BUFFERCHECK(tif)) 63 return (-1); 64 tif->tif_flags |= TIFF_BUF4WRITE; /* not strictly sure this is right*/ 65 66 td = &tif->tif_dir; 67 /* 68 * Extend image length if needed 69 * (but only for PlanarConfig=1). 70 */ 71 if (row >= td->td_imagelength) { /* extend image */ 72 if (td->td_planarconfig == PLANARCONFIG_SEPARATE) { 73 TIFFErrorExt(tif->tif_clientdata, module, 74 "Can not change \"ImageLength\" when using separate planes"); 75 return (-1); 76 } 77 td->td_imagelength = row+1; 78 imagegrew = 1; 79 } 80 /* 81 * Calculate strip and check for crossings. 82 */ 83 if (td->td_planarconfig == PLANARCONFIG_SEPARATE) { 84 if (sample >= td->td_samplesperpixel) { 85 TIFFErrorExt(tif->tif_clientdata, module, 86 "%lu: Sample out of range, max %lu", 87 (unsigned long) sample, (unsigned long) td->td_samplesperpixel); 88 return (-1); 89 } 90 strip = sample*td->td_stripsperimage + row/td->td_rowsperstrip; 91 } else 92 strip = row / td->td_rowsperstrip; 93 /* 94 * Check strip array to make sure there's space. We don't support 95 * dynamically growing files that have data organized in separate 96 * bitplanes because it's too painful. In that case we require that 97 * the imagelength be set properly before the first write (so that the 98 * strips array will be fully allocated above). 99 */ 100 if (strip >= td->td_nstrips && !TIFFGrowStrips(tif, 1, module)) 101 return (-1); 102 if (strip != tif->tif_curstrip) { 103 /* 104 * Changing strips -- flush any data present. 105 */ 106 if (!TIFFFlushData(tif)) 107 return (-1); 108 tif->tif_curstrip = strip; 109 /* 110 * Watch out for a growing image. The value of strips/image 111 * will initially be 1 (since it can't be deduced until the 112 * imagelength is known). 113 */ 114 if (strip >= td->td_stripsperimage && imagegrew) 115 td->td_stripsperimage = 116 TIFFhowmany_32(td->td_imagelength,td->td_rowsperstrip); 117 if (td->td_stripsperimage == 0) { 118 TIFFErrorExt(tif->tif_clientdata, module, "Zero strips per image"); 119 return (-1); 120 } 121 tif->tif_row = 122 (strip % td->td_stripsperimage) * td->td_rowsperstrip; 123 if ((tif->tif_flags & TIFF_CODERSETUP) == 0) { 124 if (!(*tif->tif_setupencode)(tif)) 125 return (-1); 126 tif->tif_flags |= TIFF_CODERSETUP; 127 } 128 129 tif->tif_rawcc = 0; 130 tif->tif_rawcp = tif->tif_rawdata; 131 132 if( td->td_stripbytecount[strip] > 0 ) 133 { 134 /* if we are writing over existing tiles, zero length */ 135 td->td_stripbytecount[strip] = 0; 136 137 /* this forces TIFFAppendToStrip() to do a seek */ 138 tif->tif_curoff = 0; 139 } 140 141 if (!(*tif->tif_preencode)(tif, sample)) 142 return (-1); 143 tif->tif_flags |= TIFF_POSTENCODE; 144 } 145 /* 146 * Ensure the write is either sequential or at the 147 * beginning of a strip (or that we can randomly 148 * access the data -- i.e. no encoding). 149 */ 150 if (row != tif->tif_row) { 151 if (row < tif->tif_row) { 152 /* 153 * Moving backwards within the same strip: 154 * backup to the start and then decode 155 * forward (below). 156 */ 157 tif->tif_row = (strip % td->td_stripsperimage) * 158 td->td_rowsperstrip; 159 tif->tif_rawcp = tif->tif_rawdata; 160 } 161 /* 162 * Seek forward to the desired row. 163 */ 164 if (!(*tif->tif_seek)(tif, row - tif->tif_row)) 165 return (-1); 166 tif->tif_row = row; 167 } 168 169 /* swab if needed - note that source buffer will be altered */ 170 tif->tif_postdecode( tif, (uint8*) buf, tif->tif_scanlinesize ); 171 172 status = (*tif->tif_encoderow)(tif, (uint8*) buf, 173 tif->tif_scanlinesize, sample); 174 175 /* we are now poised at the beginning of the next row */ 176 tif->tif_row = row + 1; 177 return (status); 178 } 179 180 /* 181 * Encode the supplied data and write it to the 182 * specified strip. 183 * 184 * NB: Image length must be setup before writing. 185 */ 186 tmsize_t 187 TIFFWriteEncodedStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc) 188 { 189 static const char module[] = "TIFFWriteEncodedStrip"; 190 TIFFDirectory *td = &tif->tif_dir; 191 uint16 sample; 192 193 if (!WRITECHECKSTRIPS(tif, module)) 194 return ((tmsize_t) -1); 195 /* 196 * Check strip array to make sure there's space. 197 * We don't support dynamically growing files that 198 * have data organized in separate bitplanes because 199 * it's too painful. In that case we require that 200 * the imagelength be set properly before the first 201 * write (so that the strips array will be fully 202 * allocated above). 203 */ 204 if (strip >= td->td_nstrips) { 205 if (td->td_planarconfig == PLANARCONFIG_SEPARATE) { 206 TIFFErrorExt(tif->tif_clientdata, module, 207 "Can not grow image by strips when using separate planes"); 208 return ((tmsize_t) -1); 209 } 210 if (!TIFFGrowStrips(tif, 1, module)) 211 return ((tmsize_t) -1); 212 td->td_stripsperimage = 213 TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip); 214 } 215 /* 216 * Handle delayed allocation of data buffer. This 217 * permits it to be sized according to the directory 218 * info. 219 */ 220 if (!BUFFERCHECK(tif)) 221 return ((tmsize_t) -1); 222 223 tif->tif_flags |= TIFF_BUF4WRITE; 224 tif->tif_curstrip = strip; 225 226 if (td->td_stripsperimage == 0) { 227 TIFFErrorExt(tif->tif_clientdata, module, "Zero strips per image"); 228 return ((tmsize_t) -1); 229 } 230 231 tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip; 232 if ((tif->tif_flags & TIFF_CODERSETUP) == 0) { 233 if (!(*tif->tif_setupencode)(tif)) 234 return ((tmsize_t) -1); 235 tif->tif_flags |= TIFF_CODERSETUP; 236 } 237 238 if( td->td_stripbytecount[strip] > 0 ) 239 { 240 /* Make sure that at the first attempt of rewriting the tile, we will have */ 241 /* more bytes available in the output buffer than the previous byte count, */ 242 /* so that TIFFAppendToStrip() will detect the overflow when it is called the first */ 243 /* time if the new compressed tile is bigger than the older one. (GDAL #4771) */ 244 if( tif->tif_rawdatasize <= (tmsize_t)td->td_stripbytecount[strip] ) 245 { 246 if( !(TIFFWriteBufferSetup(tif, NULL, 247 (tmsize_t)TIFFroundup_64((uint64)(td->td_stripbytecount[strip] + 1), 1024))) ) 248 return ((tmsize_t)(-1)); 249 } 250 251 /* Force TIFFAppendToStrip() to consider placing data at end 252 of file. */ 253 tif->tif_curoff = 0; 254 } 255 256 tif->tif_rawcc = 0; 257 tif->tif_rawcp = tif->tif_rawdata; 258 259 tif->tif_flags &= ~TIFF_POSTENCODE; 260 261 /* shortcut to avoid an extra memcpy() */ 262 if( td->td_compression == COMPRESSION_NONE ) 263 { 264 /* swab if needed - note that source buffer will be altered */ 265 tif->tif_postdecode( tif, (uint8*) data, cc ); 266 267 if (!isFillOrder(tif, td->td_fillorder) && 268 (tif->tif_flags & TIFF_NOBITREV) == 0) 269 TIFFReverseBits((uint8*) data, cc); 270 271 if (cc > 0 && 272 !TIFFAppendToStrip(tif, strip, (uint8*) data, cc)) 273 return ((tmsize_t) -1); 274 return (cc); 275 } 276 277 sample = (uint16)(strip / td->td_stripsperimage); 278 if (!(*tif->tif_preencode)(tif, sample)) 279 return ((tmsize_t) -1); 280 281 /* swab if needed - note that source buffer will be altered */ 282 tif->tif_postdecode( tif, (uint8*) data, cc ); 283 284 if (!(*tif->tif_encodestrip)(tif, (uint8*) data, cc, sample)) 285 return ((tmsize_t) -1); 286 if (!(*tif->tif_postencode)(tif)) 287 return ((tmsize_t) -1); 288 if (!isFillOrder(tif, td->td_fillorder) && 289 (tif->tif_flags & TIFF_NOBITREV) == 0) 290 TIFFReverseBits(tif->tif_rawdata, tif->tif_rawcc); 291 if (tif->tif_rawcc > 0 && 292 !TIFFAppendToStrip(tif, strip, tif->tif_rawdata, tif->tif_rawcc)) 293 return ((tmsize_t) -1); 294 tif->tif_rawcc = 0; 295 tif->tif_rawcp = tif->tif_rawdata; 296 return (cc); 297 } 298 299 /* 300 * Write the supplied data to the specified strip. 301 * 302 * NB: Image length must be setup before writing. 303 */ 304 tmsize_t 305 TIFFWriteRawStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc) 306 { 307 static const char module[] = "TIFFWriteRawStrip"; 308 TIFFDirectory *td = &tif->tif_dir; 309 310 if (!WRITECHECKSTRIPS(tif, module)) 311 return ((tmsize_t) -1); 312 /* 313 * Check strip array to make sure there's space. 314 * We don't support dynamically growing files that 315 * have data organized in separate bitplanes because 316 * it's too painful. In that case we require that 317 * the imagelength be set properly before the first 318 * write (so that the strips array will be fully 319 * allocated above). 320 */ 321 if (strip >= td->td_nstrips) { 322 if (td->td_planarconfig == PLANARCONFIG_SEPARATE) { 323 TIFFErrorExt(tif->tif_clientdata, module, 324 "Can not grow image by strips when using separate planes"); 325 return ((tmsize_t) -1); 326 } 327 /* 328 * Watch out for a growing image. The value of 329 * strips/image will initially be 1 (since it 330 * can't be deduced until the imagelength is known). 331 */ 332 if (strip >= td->td_stripsperimage) 333 td->td_stripsperimage = 334 TIFFhowmany_32(td->td_imagelength,td->td_rowsperstrip); 335 if (!TIFFGrowStrips(tif, 1, module)) 336 return ((tmsize_t) -1); 337 } 338 tif->tif_curstrip = strip; 339 if (td->td_stripsperimage == 0) { 340 TIFFErrorExt(tif->tif_clientdata, module,"Zero strips per image"); 341 return ((tmsize_t) -1); 342 } 343 tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip; 344 return (TIFFAppendToStrip(tif, strip, (uint8*) data, cc) ? 345 cc : (tmsize_t) -1); 346 } 347 348 /* 349 * Write and compress a tile of data. The 350 * tile is selected by the (x,y,z,s) coordinates. 351 */ 352 tmsize_t 353 TIFFWriteTile(TIFF* tif, void* buf, uint32 x, uint32 y, uint32 z, uint16 s) 354 { 355 if (!TIFFCheckTile(tif, x, y, z, s)) 356 return ((tmsize_t)(-1)); 357 /* 358 * NB: A tile size of -1 is used instead of tif_tilesize knowing 359 * that TIFFWriteEncodedTile will clamp this to the tile size. 360 * This is done because the tile size may not be defined until 361 * after the output buffer is setup in TIFFWriteBufferSetup. 362 */ 363 return (TIFFWriteEncodedTile(tif, 364 TIFFComputeTile(tif, x, y, z, s), buf, (tmsize_t)(-1))); 365 } 366 367 /* 368 * Encode the supplied data and write it to the 369 * specified tile. There must be space for the 370 * data. The function clamps individual writes 371 * to a tile to the tile size, but does not (and 372 * can not) check that multiple writes to the same 373 * tile do not write more than tile size data. 374 * 375 * NB: Image length must be setup before writing; this 376 * interface does not support automatically growing 377 * the image on each write (as TIFFWriteScanline does). 378 */ 379 tmsize_t 380 TIFFWriteEncodedTile(TIFF* tif, uint32 tile, void* data, tmsize_t cc) 381 { 382 static const char module[] = "TIFFWriteEncodedTile"; 383 TIFFDirectory *td; 384 uint16 sample; 385 uint32 howmany32; 386 387 if (!WRITECHECKTILES(tif, module)) 388 return ((tmsize_t)(-1)); 389 td = &tif->tif_dir; 390 if (tile >= td->td_nstrips) { 391 TIFFErrorExt(tif->tif_clientdata, module, "Tile %lu out of range, max %lu", 392 (unsigned long) tile, (unsigned long) td->td_nstrips); 393 return ((tmsize_t)(-1)); 394 } 395 /* 396 * Handle delayed allocation of data buffer. This 397 * permits it to be sized more intelligently (using 398 * directory information). 399 */ 400 if (!BUFFERCHECK(tif)) 401 return ((tmsize_t)(-1)); 402 403 tif->tif_flags |= TIFF_BUF4WRITE; 404 tif->tif_curtile = tile; 405 406 if( td->td_stripbytecount[tile] > 0 ) 407 { 408 /* Make sure that at the first attempt of rewriting the tile, we will have */ 409 /* more bytes available in the output buffer than the previous byte count, */ 410 /* so that TIFFAppendToStrip() will detect the overflow when it is called the first */ 411 /* time if the new compressed tile is bigger than the older one. (GDAL #4771) */ 412 if( tif->tif_rawdatasize <= (tmsize_t) td->td_stripbytecount[tile] ) 413 { 414 if( !(TIFFWriteBufferSetup(tif, NULL, 415 (tmsize_t)TIFFroundup_64((uint64)(td->td_stripbytecount[tile] + 1), 1024))) ) 416 return ((tmsize_t)(-1)); 417 } 418 419 /* Force TIFFAppendToStrip() to consider placing data at end 420 of file. */ 421 tif->tif_curoff = 0; 422 } 423 424 tif->tif_rawcc = 0; 425 tif->tif_rawcp = tif->tif_rawdata; 426 427 /* 428 * Compute tiles per row & per column to compute 429 * current row and column 430 */ 431 howmany32=TIFFhowmany_32(td->td_imagelength, td->td_tilelength); 432 if (howmany32 == 0) { 433 TIFFErrorExt(tif->tif_clientdata,module,"Zero tiles"); 434 return ((tmsize_t)(-1)); 435 } 436 tif->tif_row = (tile % howmany32) * td->td_tilelength; 437 howmany32=TIFFhowmany_32(td->td_imagewidth, td->td_tilewidth); 438 if (howmany32 == 0) { 439 TIFFErrorExt(tif->tif_clientdata,module,"Zero tiles"); 440 return ((tmsize_t)(-1)); 441 } 442 tif->tif_col = (tile % howmany32) * td->td_tilewidth; 443 444 if ((tif->tif_flags & TIFF_CODERSETUP) == 0) { 445 if (!(*tif->tif_setupencode)(tif)) 446 return ((tmsize_t)(-1)); 447 tif->tif_flags |= TIFF_CODERSETUP; 448 } 449 tif->tif_flags &= ~TIFF_POSTENCODE; 450 451 /* 452 * Clamp write amount to the tile size. This is mostly 453 * done so that callers can pass in some large number 454 * (e.g. -1) and have the tile size used instead. 455 */ 456 if ( cc < 1 || cc > tif->tif_tilesize) 457 cc = tif->tif_tilesize; 458 459 /* shortcut to avoid an extra memcpy() */ 460 if( td->td_compression == COMPRESSION_NONE ) 461 { 462 /* swab if needed - note that source buffer will be altered */ 463 tif->tif_postdecode( tif, (uint8*) data, cc ); 464 465 if (!isFillOrder(tif, td->td_fillorder) && 466 (tif->tif_flags & TIFF_NOBITREV) == 0) 467 TIFFReverseBits((uint8*) data, cc); 468 469 if (cc > 0 && 470 !TIFFAppendToStrip(tif, tile, (uint8*) data, cc)) 471 return ((tmsize_t) -1); 472 return (cc); 473 } 474 475 sample = (uint16)(tile/td->td_stripsperimage); 476 if (!(*tif->tif_preencode)(tif, sample)) 477 return ((tmsize_t)(-1)); 478 /* swab if needed - note that source buffer will be altered */ 479 tif->tif_postdecode( tif, (uint8*) data, cc ); 480 481 if (!(*tif->tif_encodetile)(tif, (uint8*) data, cc, sample)) 482 return ((tmsize_t) -1); 483 if (!(*tif->tif_postencode)(tif)) 484 return ((tmsize_t)(-1)); 485 if (!isFillOrder(tif, td->td_fillorder) && 486 (tif->tif_flags & TIFF_NOBITREV) == 0) 487 TIFFReverseBits((uint8*)tif->tif_rawdata, tif->tif_rawcc); 488 if (tif->tif_rawcc > 0 && !TIFFAppendToStrip(tif, tile, 489 tif->tif_rawdata, tif->tif_rawcc)) 490 return ((tmsize_t)(-1)); 491 tif->tif_rawcc = 0; 492 tif->tif_rawcp = tif->tif_rawdata; 493 return (cc); 494 } 495 496 /* 497 * Write the supplied data to the specified strip. 498 * There must be space for the data; we don't check 499 * if strips overlap! 500 * 501 * NB: Image length must be setup before writing; this 502 * interface does not support automatically growing 503 * the image on each write (as TIFFWriteScanline does). 504 */ 505 tmsize_t 506 TIFFWriteRawTile(TIFF* tif, uint32 tile, void* data, tmsize_t cc) 507 { 508 static const char module[] = "TIFFWriteRawTile"; 509 510 if (!WRITECHECKTILES(tif, module)) 511 return ((tmsize_t)(-1)); 512 if (tile >= tif->tif_dir.td_nstrips) { 513 TIFFErrorExt(tif->tif_clientdata, module, "Tile %lu out of range, max %lu", 514 (unsigned long) tile, 515 (unsigned long) tif->tif_dir.td_nstrips); 516 return ((tmsize_t)(-1)); 517 } 518 return (TIFFAppendToStrip(tif, tile, (uint8*) data, cc) ? 519 cc : (tmsize_t)(-1)); 520 } 521 522 #define isUnspecified(tif, f) \ 523 (TIFFFieldSet(tif,f) && (tif)->tif_dir.td_imagelength == 0) 524 525 int 526 TIFFSetupStrips(TIFF* tif) 527 { 528 TIFFDirectory* td = &tif->tif_dir; 529 530 if (isTiled(tif)) 531 td->td_stripsperimage = 532 isUnspecified(tif, FIELD_TILEDIMENSIONS) ? 533 td->td_samplesperpixel : TIFFNumberOfTiles(tif); 534 else 535 td->td_stripsperimage = 536 isUnspecified(tif, FIELD_ROWSPERSTRIP) ? 537 td->td_samplesperpixel : TIFFNumberOfStrips(tif); 538 td->td_nstrips = td->td_stripsperimage; 539 if (td->td_planarconfig == PLANARCONFIG_SEPARATE) 540 td->td_stripsperimage /= td->td_samplesperpixel; 541 td->td_stripoffset = (uint64 *) 542 _TIFFCheckMalloc(tif, td->td_nstrips, sizeof (uint64), 543 "for \"StripOffsets\" array"); 544 td->td_stripbytecount = (uint64 *) 545 _TIFFCheckMalloc(tif, td->td_nstrips, sizeof (uint64), 546 "for \"StripByteCounts\" array"); 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