tif_write.c
上传用户:looem2003
上传日期:2014-07-20
资源大小:13733k
文件大小:22k
源码类别:

打印编程

开发平台:

Visual C++

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