]>
git.saurik.com Git - wxWidgets.git/blob - src/tiff/libtiff/tif_write.c
   4  * Copyright (c) 1988-1997 Sam Leffler 
   5  * Copyright (c) 1991-1997 Silicon Graphics, Inc. 
   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. 
  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.   
  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  
  30  * Scanline-oriented Write Support 
  35 #define STRIPINCR       20              /* expansion factor on strip array */ 
  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, (tsize_t) -1)) 
  45 static  int TIFFGrowStrips(TIFF
*, int, const char*); 
  46 static  int TIFFAppendToStrip(TIFF
*, tstrip_t
, tidata_t
, tsize_t
); 
  49 TIFFWriteScanline(TIFF
* tif
, tdata_t buf
, uint32 row
, tsample_t sample
) 
  51         static const char module[] = "TIFFWriteScanline"; 
  52         register TIFFDirectory 
*td
; 
  53         int status
, imagegrew 
= 0; 
  56         if (!WRITECHECKSTRIPS(tif
, module)) 
  59          * Handle delayed allocation of data buffer.  This 
  60          * permits it to be sized more intelligently (using 
  61          * directory information). 
  63         if (!BUFFERCHECK(tif
)) 
  67          * Extend image length if needed 
  68          * (but only for PlanarConfig=1). 
  70         if (row 
>= td
->td_imagelength
) {        /* extend image */ 
  71                 if (td
->td_planarconfig 
== PLANARCONFIG_SEPARATE
) { 
  72                         TIFFErrorExt(tif
->tif_clientdata
, tif
->tif_name
, 
  73                 "Can not change \"ImageLength\" when using separate planes"); 
  76                 td
->td_imagelength 
= row
+1; 
  80          * Calculate strip and check for crossings. 
  82         if (td
->td_planarconfig 
== PLANARCONFIG_SEPARATE
) { 
  83                 if (sample 
>= td
->td_samplesperpixel
) { 
  84                         TIFFErrorExt(tif
->tif_clientdata
, tif
->tif_name
, 
  85                             "%d: Sample out of range, max %d", 
  86                             sample
, td
->td_samplesperpixel
); 
  89                 strip 
= sample
*td
->td_stripsperimage 
+ row
/td
->td_rowsperstrip
; 
  91                 strip 
= row 
/ td
->td_rowsperstrip
; 
  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). 
  99         if (strip 
>= td
->td_nstrips 
&& !TIFFGrowStrips(tif
, 1, module)) 
 101         if (strip 
!= tif
->tif_curstrip
) { 
 103                  * Changing strips -- flush any data present. 
 105                 if (!TIFFFlushData(tif
)) 
 107                 tif
->tif_curstrip 
= strip
; 
 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). 
 113                 if (strip 
>= td
->td_stripsperimage 
&& imagegrew
) 
 114                         td
->td_stripsperimage 
= 
 115                             TIFFhowmany(td
->td_imagelength
,td
->td_rowsperstrip
); 
 117                     (strip 
% td
->td_stripsperimage
) * td
->td_rowsperstrip
; 
 118                 if ((tif
->tif_flags 
& TIFF_CODERSETUP
) == 0) { 
 119                         if (!(*tif
->tif_setupencode
)(tif
)) 
 121                         tif
->tif_flags 
|= TIFF_CODERSETUP
; 
 125                 tif
->tif_rawcp 
= tif
->tif_rawdata
; 
 127                 if( td
->td_stripbytecount
[strip
] > 0 ) 
 129                         /* if we are writing over existing tiles, zero length */ 
 130                         td
->td_stripbytecount
[strip
] = 0; 
 132                         /* this forces TIFFAppendToStrip() to do a seek */ 
 136                 if (!(*tif
->tif_preencode
)(tif
, sample
)) 
 138                 tif
->tif_flags 
|= TIFF_POSTENCODE
; 
 141          * Ensure the write is either sequential or at the 
 142          * beginning of a strip (or that we can randomly 
 143          * access the data -- i.e. no encoding). 
 145         if (row 
!= tif
->tif_row
) { 
 146                 if (row 
< tif
->tif_row
) { 
 148                          * Moving backwards within the same strip: 
 149                          * backup to the start and then decode 
 152                         tif
->tif_row 
= (strip 
% td
->td_stripsperimage
) * 
 154                         tif
->tif_rawcp 
= tif
->tif_rawdata
; 
 157                  * Seek forward to the desired row. 
 159                 if (!(*tif
->tif_seek
)(tif
, row 
- tif
->tif_row
)) 
 164         /* swab if needed - note that source buffer will be altered */ 
 165         tif
->tif_postdecode( tif
, (tidata_t
) buf
, tif
->tif_scanlinesize 
); 
 167         status 
= (*tif
->tif_encoderow
)(tif
, (tidata_t
) buf
, 
 168             tif
->tif_scanlinesize
, sample
); 
 170         /* we are now poised at the beginning of the next row */ 
 171         tif
->tif_row 
= row 
+ 1; 
 176  * Encode the supplied data and write it to the 
 179  * NB: Image length must be setup before writing. 
 182 TIFFWriteEncodedStrip(TIFF
* tif
, tstrip_t strip
, tdata_t data
, tsize_t cc
) 
 184         static const char module[] = "TIFFWriteEncodedStrip"; 
 185         TIFFDirectory 
*td 
= &tif
->tif_dir
; 
 188         if (!WRITECHECKSTRIPS(tif
, module)) 
 189                 return ((tsize_t
) -1); 
 191          * Check strip array to make sure there's space. 
 192          * We don't support dynamically growing files that 
 193          * have data organized in separate bitplanes because 
 194          * it's too painful.  In that case we require that 
 195          * the imagelength be set properly before the first 
 196          * write (so that the strips array will be fully 
 199         if (strip 
>= td
->td_nstrips
) { 
 200                 if (td
->td_planarconfig 
== PLANARCONFIG_SEPARATE
) { 
 201                         TIFFErrorExt(tif
->tif_clientdata
, tif
->tif_name
, 
 202                 "Can not grow image by strips when using separate planes"); 
 203                         return ((tsize_t
) -1); 
 205                 if (!TIFFGrowStrips(tif
, 1, module)) 
 206                         return ((tsize_t
) -1); 
 207                 td
->td_stripsperimage 
= 
 208                     TIFFhowmany(td
->td_imagelength
, td
->td_rowsperstrip
); 
 211          * Handle delayed allocation of data buffer.  This 
 212          * permits it to be sized according to the directory 
 215         if (!BUFFERCHECK(tif
)) 
 216                 return ((tsize_t
) -1); 
 217         tif
->tif_curstrip 
= strip
; 
 218         tif
->tif_row 
= (strip 
% td
->td_stripsperimage
) * td
->td_rowsperstrip
; 
 219         if ((tif
->tif_flags 
& TIFF_CODERSETUP
) == 0) { 
 220                 if (!(*tif
->tif_setupencode
)(tif
)) 
 221                         return ((tsize_t
) -1); 
 222                 tif
->tif_flags 
|= TIFF_CODERSETUP
; 
 226         tif
->tif_rawcp 
= tif
->tif_rawdata
; 
 228         if( td
->td_stripbytecount
[strip
] > 0 ) 
 230             /* if we are writing over existing tiles, zero length. */ 
 231             td
->td_stripbytecount
[strip
] = 0; 
 233             /* this forces TIFFAppendToStrip() to do a seek */ 
 237         tif
->tif_flags 
&= ~TIFF_POSTENCODE
; 
 238         sample 
= (tsample_t
)(strip 
/ td
->td_stripsperimage
); 
 239         if (!(*tif
->tif_preencode
)(tif
, sample
)) 
 240                 return ((tsize_t
) -1); 
 242         /* swab if needed - note that source buffer will be altered */ 
 243         tif
->tif_postdecode( tif
, (tidata_t
) data
, cc 
); 
 245         if (!(*tif
->tif_encodestrip
)(tif
, (tidata_t
) data
, cc
, sample
)) 
 246                 return ((tsize_t
) 0); 
 247         if (!(*tif
->tif_postencode
)(tif
)) 
 248                 return ((tsize_t
) -1); 
 249         if (!isFillOrder(tif
, td
->td_fillorder
) && 
 250             (tif
->tif_flags 
& TIFF_NOBITREV
) == 0) 
 251                 TIFFReverseBits(tif
->tif_rawdata
, tif
->tif_rawcc
); 
 252         if (tif
->tif_rawcc 
> 0 && 
 253             !TIFFAppendToStrip(tif
, strip
, tif
->tif_rawdata
, tif
->tif_rawcc
)) 
 254                 return ((tsize_t
) -1); 
 256         tif
->tif_rawcp 
= tif
->tif_rawdata
; 
 261  * Write the supplied data to the specified strip. 
 263  * NB: Image length must be setup before writing. 
 266 TIFFWriteRawStrip(TIFF
* tif
, tstrip_t strip
, tdata_t data
, tsize_t cc
) 
 268         static const char module[] = "TIFFWriteRawStrip"; 
 269         TIFFDirectory 
*td 
= &tif
->tif_dir
; 
 271         if (!WRITECHECKSTRIPS(tif
, module)) 
 272                 return ((tsize_t
) -1); 
 274          * Check strip array to make sure there's space. 
 275          * We don't support dynamically growing files that 
 276          * have data organized in separate bitplanes because 
 277          * it's too painful.  In that case we require that 
 278          * the imagelength be set properly before the first 
 279          * write (so that the strips array will be fully 
 282         if (strip 
>= td
->td_nstrips
) { 
 283                 if (td
->td_planarconfig 
== PLANARCONFIG_SEPARATE
) { 
 284                         TIFFErrorExt(tif
->tif_clientdata
, tif
->tif_name
, 
 285                 "Can not grow image by strips when using separate planes"); 
 286                         return ((tsize_t
) -1); 
 289                  * Watch out for a growing image.  The value of 
 290                  * strips/image will initially be 1 (since it 
 291                  * can't be deduced until the imagelength is known). 
 293                 if (strip 
>= td
->td_stripsperimage
) 
 294                         td
->td_stripsperimage 
= 
 295                             TIFFhowmany(td
->td_imagelength
,td
->td_rowsperstrip
); 
 296                 if (!TIFFGrowStrips(tif
, 1, module)) 
 297                         return ((tsize_t
) -1); 
 299         tif
->tif_curstrip 
= strip
; 
 300         tif
->tif_row 
= (strip 
% td
->td_stripsperimage
) * td
->td_rowsperstrip
; 
 301         return (TIFFAppendToStrip(tif
, strip
, (tidata_t
) data
, cc
) ? 
 306  * Write and compress a tile of data.  The 
 307  * tile is selected by the (x,y,z,s) coordinates. 
 310 TIFFWriteTile(TIFF
* tif
, 
 311     tdata_t buf
, uint32 x
, uint32 y
, uint32 z
, tsample_t s
) 
 313         if (!TIFFCheckTile(tif
, x
, y
, z
, s
)) 
 316          * NB: A tile size of -1 is used instead of tif_tilesize knowing 
 317          *     that TIFFWriteEncodedTile will clamp this to the tile size. 
 318          *     This is done because the tile size may not be defined until 
 319          *     after the output buffer is setup in TIFFWriteBufferSetup. 
 321         return (TIFFWriteEncodedTile(tif
, 
 322             TIFFComputeTile(tif
, x
, y
, z
, s
), buf
, (tsize_t
) -1)); 
 326  * Encode the supplied data and write it to the 
 327  * specified tile.  There must be space for the 
 328  * data.  The function clamps individual writes 
 329  * to a tile to the tile size, but does not (and 
 330  * can not) check that multiple writes to the same 
 331  * tile do not write more than tile size data. 
 333  * NB: Image length must be setup before writing; this 
 334  *     interface does not support automatically growing 
 335  *     the image on each write (as TIFFWriteScanline does). 
 338 TIFFWriteEncodedTile(TIFF
* tif
, ttile_t tile
, tdata_t data
, tsize_t cc
) 
 340         static const char module[] = "TIFFWriteEncodedTile"; 
 344         if (!WRITECHECKTILES(tif
, module)) 
 345                 return ((tsize_t
) -1); 
 347         if (tile 
>= td
->td_nstrips
) { 
 348                 TIFFErrorExt(tif
->tif_clientdata
, module, "%s: Tile %lu out of range, max %lu", 
 349                     tif
->tif_name
, (unsigned long) tile
, (unsigned long) td
->td_nstrips
); 
 350                 return ((tsize_t
) -1); 
 353          * Handle delayed allocation of data buffer.  This 
 354          * permits it to be sized more intelligently (using 
 355          * directory information). 
 357         if (!BUFFERCHECK(tif
)) 
 358                 return ((tsize_t
) -1); 
 359         tif
->tif_curtile 
= tile
; 
 362         tif
->tif_rawcp 
= tif
->tif_rawdata
; 
 364         if( td
->td_stripbytecount
[tile
] > 0 ) 
 366             /* if we are writing over existing tiles, zero length. */ 
 367             td
->td_stripbytecount
[tile
] = 0; 
 369             /* this forces TIFFAppendToStrip() to do a seek */ 
 374          * Compute tiles per row & per column to compute 
 375          * current row and column 
 377         tif
->tif_row 
= (tile 
% TIFFhowmany(td
->td_imagelength
, td
->td_tilelength
)) 
 379         tif
->tif_col 
= (tile 
% TIFFhowmany(td
->td_imagewidth
, td
->td_tilewidth
)) 
 382         if ((tif
->tif_flags 
& TIFF_CODERSETUP
) == 0) { 
 383                 if (!(*tif
->tif_setupencode
)(tif
)) 
 384                         return ((tsize_t
) -1); 
 385                 tif
->tif_flags 
|= TIFF_CODERSETUP
; 
 387         tif
->tif_flags 
&= ~TIFF_POSTENCODE
; 
 388         sample 
= (tsample_t
)(tile
/td
->td_stripsperimage
); 
 389         if (!(*tif
->tif_preencode
)(tif
, sample
)) 
 390                 return ((tsize_t
) -1); 
 392          * Clamp write amount to the tile size.  This is mostly 
 393          * done so that callers can pass in some large number 
 394          * (e.g. -1) and have the tile size used instead. 
 396         if ( cc 
< 1 || cc 
> tif
->tif_tilesize
) 
 397                 cc 
= tif
->tif_tilesize
; 
 399         /* swab if needed - note that source buffer will be altered */ 
 400         tif
->tif_postdecode( tif
, (tidata_t
) data
, cc 
); 
 402         if (!(*tif
->tif_encodetile
)(tif
, (tidata_t
) data
, cc
, sample
)) 
 403                 return ((tsize_t
) 0); 
 404         if (!(*tif
->tif_postencode
)(tif
)) 
 405                 return ((tsize_t
) -1); 
 406         if (!isFillOrder(tif
, td
->td_fillorder
) && 
 407             (tif
->tif_flags 
& TIFF_NOBITREV
) == 0) 
 408                 TIFFReverseBits((unsigned char *)tif
->tif_rawdata
, tif
->tif_rawcc
); 
 409         if (tif
->tif_rawcc 
> 0 && !TIFFAppendToStrip(tif
, tile
, 
 410             tif
->tif_rawdata
, tif
->tif_rawcc
)) 
 411                 return ((tsize_t
) -1); 
 413         tif
->tif_rawcp 
= tif
->tif_rawdata
; 
 418  * Write the supplied data to the specified strip. 
 419  * There must be space for the data; we don't check 
 422  * NB: Image length must be setup before writing; this 
 423  *     interface does not support automatically growing 
 424  *     the image on each write (as TIFFWriteScanline does). 
 427 TIFFWriteRawTile(TIFF
* tif
, ttile_t tile
, tdata_t data
, tsize_t cc
) 
 429         static const char module[] = "TIFFWriteRawTile"; 
 431         if (!WRITECHECKTILES(tif
, module)) 
 432                 return ((tsize_t
) -1); 
 433         if (tile 
>= tif
->tif_dir
.td_nstrips
) { 
 434                 TIFFErrorExt(tif
->tif_clientdata
, module, "%s: Tile %lu out of range, max %lu", 
 435                     tif
->tif_name
, (unsigned long) tile
, 
 436                     (unsigned long) tif
->tif_dir
.td_nstrips
); 
 437                 return ((tsize_t
) -1); 
 439         return (TIFFAppendToStrip(tif
, tile
, (tidata_t
) data
, cc
) ? 
 443 #define isUnspecified(tif, f) \ 
 444     (TIFFFieldSet(tif,f) && (tif)->tif_dir.td_imagelength == 0) 
 447 TIFFSetupStrips(TIFF
* tif
) 
 449         TIFFDirectory
* td 
= &tif
->tif_dir
; 
 452                 td
->td_stripsperimage 
= 
 453                     isUnspecified(tif
, FIELD_TILEDIMENSIONS
) ? 
 454                         td
->td_samplesperpixel 
: TIFFNumberOfTiles(tif
); 
 456                 td
->td_stripsperimage 
= 
 457                     isUnspecified(tif
, FIELD_ROWSPERSTRIP
) ? 
 458                         td
->td_samplesperpixel 
: TIFFNumberOfStrips(tif
); 
 459         td
->td_nstrips 
= td
->td_stripsperimage
; 
 460         if (td
->td_planarconfig 
== PLANARCONFIG_SEPARATE
) 
 461                 td
->td_stripsperimage 
/= td
->td_samplesperpixel
; 
 462         td
->td_stripoffset 
= (uint32 
*) 
 463             _TIFFmalloc(td
->td_nstrips 
* sizeof (uint32
)); 
 464         td
->td_stripbytecount 
= (uint32 
*) 
 465             _TIFFmalloc(td
->td_nstrips 
* sizeof (uint32
)); 
 466         if (td
->td_stripoffset 
== NULL 
|| td
->td_stripbytecount 
== NULL
) 
 469          * Place data at the end-of-file 
 470          * (by setting offsets to zero). 
 472         _TIFFmemset(td
->td_stripoffset
, 0, td
->td_nstrips
*sizeof (uint32
)); 
 473         _TIFFmemset(td
->td_stripbytecount
, 0, td
->td_nstrips
*sizeof (uint32
)); 
 474         TIFFSetFieldBit(tif
, FIELD_STRIPOFFSETS
); 
 475         TIFFSetFieldBit(tif
, FIELD_STRIPBYTECOUNTS
); 
 481  * Verify file is writable and that the directory 
 482  * information is setup properly.  In doing the latter 
 483  * we also "freeze" the state of the directory so 
 484  * that important information is not changed. 
 487 TIFFWriteCheck(TIFF
* tif
, int tiles
, const char* module) 
 489         if (tif
->tif_mode 
== O_RDONLY
) { 
 490                 TIFFErrorExt(tif
->tif_clientdata
, module, "%s: File not open for writing", 
 494         if (tiles 
^ isTiled(tif
)) { 
 495                 TIFFErrorExt(tif
->tif_clientdata
, tif
->tif_name
, tiles 
? 
 496                     "Can not write tiles to a stripped image" : 
 497                     "Can not write scanlines to a tiled image"); 
 502          * On the first write verify all the required information 
 503          * has been setup and initialize any data structures that 
 504          * had to wait until directory information was set. 
 505          * Note that a lot of our work is assumed to remain valid 
 506          * because we disallow any of the important parameters 
 507          * from changing after we start writing (i.e. once 
 508          * TIFF_BEENWRITING is set, TIFFSetField will only allow 
 509          * the image's length to be changed). 
 511         if (!TIFFFieldSet(tif
, FIELD_IMAGEDIMENSIONS
)) { 
 512                 TIFFErrorExt(tif
->tif_clientdata
, module, 
 513                     "%s: Must set \"ImageWidth\" before writing data", 
 517         if (tif
->tif_dir
.td_samplesperpixel 
== 1) { 
 519                  * Planarconfiguration is irrelevant in case of single band 
 520                  * images and need not be included. We will set it anyway, 
 521                  * because this field is used in other parts of library even 
 522                  * in the single band case. 
 524                 tif
->tif_dir
.td_planarconfig 
= PLANARCONFIG_CONTIG
; 
 526                 if (!TIFFFieldSet(tif
, FIELD_PLANARCONFIG
)) { 
 527                         TIFFErrorExt(tif
->tif_clientdata
, module, 
 528                     "%s: Must set \"PlanarConfiguration\" before writing data", 
 533         if (tif
->tif_dir
.td_stripoffset 
== NULL 
&& !TIFFSetupStrips(tif
)) { 
 534                 tif
->tif_dir
.td_nstrips 
= 0; 
 535                 TIFFErrorExt(tif
->tif_clientdata
, module, "%s: No space for %s arrays", 
 536                     tif
->tif_name
, isTiled(tif
) ? "tile" : "strip"); 
 539         tif
->tif_tilesize 
= isTiled(tif
) ? TIFFTileSize(tif
) : (tsize_t
) -1; 
 540         tif
->tif_scanlinesize 
= TIFFScanlineSize(tif
); 
 541         tif
->tif_flags 
|= TIFF_BEENWRITING
; 
 546  * Setup the raw data buffer used for encoding. 
 549 TIFFWriteBufferSetup(TIFF
* tif
, tdata_t bp
, tsize_t size
) 
 551         static const char module[] = "TIFFWriteBufferSetup"; 
 553         if (tif
->tif_rawdata
) { 
 554                 if (tif
->tif_flags 
& TIFF_MYBUFFER
) { 
 555                         _TIFFfree(tif
->tif_rawdata
); 
 556                         tif
->tif_flags 
&= ~TIFF_MYBUFFER
; 
 558                 tif
->tif_rawdata 
= NULL
; 
 560         if (size 
== (tsize_t
) -1) { 
 561                 size 
= (isTiled(tif
) ? 
 562                     tif
->tif_tilesize 
: TIFFStripSize(tif
)); 
 564                  * Make raw data buffer at least 8K 
 568                 bp 
= NULL
;                      /* NB: force malloc */ 
 571                 bp 
= _TIFFmalloc(size
); 
 573                         TIFFErrorExt(tif
->tif_clientdata
, module, "%s: No space for output buffer", 
 577                 tif
->tif_flags 
|= TIFF_MYBUFFER
; 
 579                 tif
->tif_flags 
&= ~TIFF_MYBUFFER
; 
 580         tif
->tif_rawdata 
= (tidata_t
) bp
; 
 581         tif
->tif_rawdatasize 
= size
; 
 583         tif
->tif_rawcp 
= tif
->tif_rawdata
; 
 584         tif
->tif_flags 
|= TIFF_BUFFERSETUP
; 
 589  * Grow the strip data structures by delta strips. 
 592 TIFFGrowStrips(TIFF
* tif
, int delta
, const char* module) 
 594         TIFFDirectory   
*td 
= &tif
->tif_dir
; 
 595         uint32          
*new_stripoffset
, *new_stripbytecount
; 
 597         assert(td
->td_planarconfig 
== PLANARCONFIG_CONTIG
); 
 598         new_stripoffset 
= (uint32
*)_TIFFrealloc(td
->td_stripoffset
, 
 599                 (td
->td_nstrips 
+ delta
) * sizeof (uint32
)); 
 600         new_stripbytecount 
= (uint32
*)_TIFFrealloc(td
->td_stripbytecount
, 
 601                 (td
->td_nstrips 
+ delta
) * sizeof (uint32
)); 
 602         if (new_stripoffset 
== NULL 
|| new_stripbytecount 
== NULL
) { 
 604                         _TIFFfree(new_stripoffset
); 
 605                 if (new_stripbytecount
) 
 606                         _TIFFfree(new_stripbytecount
); 
 608                 TIFFErrorExt(tif
->tif_clientdata
, module, "%s: No space to expand strip arrays", 
 612         td
->td_stripoffset 
= new_stripoffset
; 
 613         td
->td_stripbytecount 
= new_stripbytecount
; 
 614         _TIFFmemset(td
->td_stripoffset 
+ td
->td_nstrips
, 
 615                     0, delta
*sizeof (uint32
)); 
 616         _TIFFmemset(td
->td_stripbytecount 
+ td
->td_nstrips
, 
 617                     0, delta
*sizeof (uint32
)); 
 618         td
->td_nstrips 
+= delta
; 
 623  * Append the data to the specified strip. 
 626 TIFFAppendToStrip(TIFF
* tif
, tstrip_t strip
, tidata_t data
, tsize_t cc
) 
 628         TIFFDirectory 
*td 
= &tif
->tif_dir
; 
 629         static const char module[] = "TIFFAppendToStrip"; 
 631         if (td
->td_stripoffset
[strip
] == 0 || tif
->tif_curoff 
== 0) { 
 633                  * No current offset, set the current strip. 
 635                 assert(td
->td_nstrips 
> 0); 
 636                 if (td
->td_stripoffset
[strip
] != 0) { 
 638                          * Prevent overlapping of the data chunks. We need 
 639                          * this to enable in place updating of the compressed 
 640                          * images. Larger blocks will be moved at the end of 
 641                          * the file without any optimization of the spare 
 642                          * space, so such scheme is not too much effective. 
 644                         if (td
->td_stripbytecountsorted
) { 
 645                                 if (strip 
== td
->td_nstrips 
- 1 
 646                                     || td
->td_stripoffset
[strip 
+ 1] < 
 647                                         td
->td_stripoffset
[strip
] + cc
) { 
 648                                         td
->td_stripoffset
[strip
] = 
 649                                                 TIFFSeekFile(tif
, (toff_t
)0, 
 654                                 for (i 
= 0; i 
< td
->td_nstrips
; i
++) { 
 655                                         if (td
->td_stripoffset
[i
] >  
 656                                                 td
->td_stripoffset
[strip
] 
 657                                             && td
->td_stripoffset
[i
] < 
 658                                                 td
->td_stripoffset
[strip
] + cc
) { 
 659                                                 td
->td_stripoffset
[strip
] = 
 667                         if (!SeekOK(tif
, td
->td_stripoffset
[strip
])) { 
 668                                 TIFFErrorExt(tif
->tif_clientdata
, module, 
 669                                           "%s: Seek error at scanline %lu", 
 671                                           (unsigned long)tif
->tif_row
); 
 675                         td
->td_stripoffset
[strip
] = 
 676                             TIFFSeekFile(tif
, (toff_t
) 0, SEEK_END
); 
 677                 tif
->tif_curoff 
= td
->td_stripoffset
[strip
]; 
 680         if (!WriteOK(tif
, data
, cc
)) { 
 681                 TIFFErrorExt(tif
->tif_clientdata
, module, "%s: Write error at scanline %lu", 
 682                     tif
->tif_name
, (unsigned long) tif
->tif_row
); 
 685         tif
->tif_curoff 
+= cc
; 
 686         td
->td_stripbytecount
[strip
] += cc
; 
 691  * Internal version of TIFFFlushData that can be 
 692  * called by ``encodestrip routines'' w/o concern 
 693  * for infinite recursion. 
 696 TIFFFlushData1(TIFF
* tif
) 
 698         if (tif
->tif_rawcc 
> 0) { 
 699                 if (!isFillOrder(tif
, tif
->tif_dir
.td_fillorder
) && 
 700                     (tif
->tif_flags 
& TIFF_NOBITREV
) == 0) 
 701                         TIFFReverseBits((unsigned char *)tif
->tif_rawdata
, 
 703                 if (!TIFFAppendToStrip(tif
, 
 704                     isTiled(tif
) ? tif
->tif_curtile 
: tif
->tif_curstrip
, 
 705                     tif
->tif_rawdata
, tif
->tif_rawcc
)) 
 708                 tif
->tif_rawcp 
= tif
->tif_rawdata
; 
 714  * Set the current write offset.  This should only be 
 715  * used to set the offset to a known previous location 
 716  * (very carefully), or to 0 so that the next write gets 
 717  * appended to the end of the file. 
 720 TIFFSetWriteOffset(TIFF
* tif
, toff_t off
) 
 722         tif
->tif_curoff 
= off
; 
 725 /* vim: set ts=8 sts=8 sw=8 noet: */