/src/FreeImage/Source/LibTIFF/tif_write.c

https://bitbucket.org/cabalistic/ogredeps/ · C · 718 lines · 432 code · 52 blank · 234 comment · 120 complexity · 03c2574b07b73562ee0e7ec7320bbda0 MD5 · raw file

  1. /* $Id: tif_write.c,v 1.37 2011/04/10 17:14:09 drolon 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. tif->tif_rawcc = 0;
  117. tif->tif_rawcp = tif->tif_rawdata;
  118. if( td->td_stripbytecount[strip] > 0 )
  119. {
  120. /* if we are writing over existing tiles, zero length */
  121. td->td_stripbytecount[strip] = 0;
  122. /* this forces TIFFAppendToStrip() to do a seek */
  123. tif->tif_curoff = 0;
  124. }
  125. if (!(*tif->tif_preencode)(tif, sample))
  126. return (-1);
  127. tif->tif_flags |= TIFF_POSTENCODE;
  128. }
  129. /*
  130. * Ensure the write is either sequential or at the
  131. * beginning of a strip (or that we can randomly
  132. * access the data -- i.e. no encoding).
  133. */
  134. if (row != tif->tif_row) {
  135. if (row < tif->tif_row) {
  136. /*
  137. * Moving backwards within the same strip:
  138. * backup to the start and then decode
  139. * forward (below).
  140. */
  141. tif->tif_row = (strip % td->td_stripsperimage) *
  142. td->td_rowsperstrip;
  143. tif->tif_rawcp = tif->tif_rawdata;
  144. }
  145. /*
  146. * Seek forward to the desired row.
  147. */
  148. if (!(*tif->tif_seek)(tif, row - tif->tif_row))
  149. return (-1);
  150. tif->tif_row = row;
  151. }
  152. /* swab if needed - note that source buffer will be altered */
  153. tif->tif_postdecode( tif, (tidata_t) buf, tif->tif_scanlinesize );
  154. status = (*tif->tif_encoderow)(tif, (tidata_t) buf,
  155. tif->tif_scanlinesize, sample);
  156. /* we are now poised at the beginning of the next row */
  157. tif->tif_row = row + 1;
  158. return (status);
  159. }
  160. /*
  161. * Encode the supplied data and write it to the
  162. * specified strip.
  163. *
  164. * NB: Image length must be setup before writing.
  165. */
  166. tsize_t
  167. TIFFWriteEncodedStrip(TIFF* tif, tstrip_t strip, tdata_t data, tsize_t cc)
  168. {
  169. static const char module[] = "TIFFWriteEncodedStrip";
  170. TIFFDirectory *td = &tif->tif_dir;
  171. tsample_t sample;
  172. if (!WRITECHECKSTRIPS(tif, module))
  173. return ((tsize_t) -1);
  174. /*
  175. * Check strip array to make sure there's space.
  176. * We don't support dynamically growing files that
  177. * have data organized in separate bitplanes because
  178. * it's too painful. In that case we require that
  179. * the imagelength be set properly before the first
  180. * write (so that the strips array will be fully
  181. * allocated above).
  182. */
  183. if (strip >= td->td_nstrips) {
  184. if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
  185. TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
  186. "Can not grow image by strips when using separate planes");
  187. return ((tsize_t) -1);
  188. }
  189. if (!TIFFGrowStrips(tif, 1, module))
  190. return ((tsize_t) -1);
  191. td->td_stripsperimage =
  192. TIFFhowmany(td->td_imagelength, td->td_rowsperstrip);
  193. }
  194. /*
  195. * Handle delayed allocation of data buffer. This
  196. * permits it to be sized according to the directory
  197. * info.
  198. */
  199. if (!BUFFERCHECK(tif))
  200. return ((tsize_t) -1);
  201. tif->tif_curstrip = strip;
  202. tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
  203. if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
  204. if (!(*tif->tif_setupencode)(tif))
  205. return ((tsize_t) -1);
  206. tif->tif_flags |= TIFF_CODERSETUP;
  207. }
  208. tif->tif_rawcc = 0;
  209. tif->tif_rawcp = tif->tif_rawdata;
  210. if( td->td_stripbytecount[strip] > 0 )
  211. {
  212. /* Force TIFFAppendToStrip() to consider placing data at end
  213. of file. */
  214. tif->tif_curoff = 0;
  215. }
  216. tif->tif_flags &= ~TIFF_POSTENCODE;
  217. sample = (tsample_t)(strip / td->td_stripsperimage);
  218. if (!(*tif->tif_preencode)(tif, sample))
  219. return ((tsize_t) -1);
  220. /* swab if needed - note that source buffer will be altered */
  221. tif->tif_postdecode( tif, (tidata_t) data, cc );
  222. if (!(*tif->tif_encodestrip)(tif, (tidata_t) data, cc, sample))
  223. return ((tsize_t) 0);
  224. if (!(*tif->tif_postencode)(tif))
  225. return ((tsize_t) -1);
  226. if (!isFillOrder(tif, td->td_fillorder) &&
  227. (tif->tif_flags & TIFF_NOBITREV) == 0)
  228. TIFFReverseBits(tif->tif_rawdata, tif->tif_rawcc);
  229. if (tif->tif_rawcc > 0 &&
  230. !TIFFAppendToStrip(tif, strip, tif->tif_rawdata, tif->tif_rawcc))
  231. return ((tsize_t) -1);
  232. tif->tif_rawcc = 0;
  233. tif->tif_rawcp = tif->tif_rawdata;
  234. return (cc);
  235. }
  236. /*
  237. * Write the supplied data to the specified strip.
  238. *
  239. * NB: Image length must be setup before writing.
  240. */
  241. tsize_t
  242. TIFFWriteRawStrip(TIFF* tif, tstrip_t strip, tdata_t data, tsize_t cc)
  243. {
  244. static const char module[] = "TIFFWriteRawStrip";
  245. TIFFDirectory *td = &tif->tif_dir;
  246. if (!WRITECHECKSTRIPS(tif, module))
  247. return ((tsize_t) -1);
  248. /*
  249. * Check strip array to make sure there's space.
  250. * We don't support dynamically growing files that
  251. * have data organized in separate bitplanes because
  252. * it's too painful. In that case we require that
  253. * the imagelength be set properly before the first
  254. * write (so that the strips array will be fully
  255. * allocated above).
  256. */
  257. if (strip >= td->td_nstrips) {
  258. if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
  259. TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
  260. "Can not grow image by strips when using separate planes");
  261. return ((tsize_t) -1);
  262. }
  263. /*
  264. * Watch out for a growing image. The value of
  265. * strips/image will initially be 1 (since it
  266. * can't be deduced until the imagelength is known).
  267. */
  268. if (strip >= td->td_stripsperimage)
  269. td->td_stripsperimage =
  270. TIFFhowmany(td->td_imagelength,td->td_rowsperstrip);
  271. if (!TIFFGrowStrips(tif, 1, module))
  272. return ((tsize_t) -1);
  273. }
  274. tif->tif_curstrip = strip;
  275. tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
  276. return (TIFFAppendToStrip(tif, strip, (tidata_t) data, cc) ?
  277. cc : (tsize_t) -1);
  278. }
  279. /*
  280. * Write and compress a tile of data. The
  281. * tile is selected by the (x,y,z,s) coordinates.
  282. */
  283. tsize_t
  284. TIFFWriteTile(TIFF* tif,
  285. tdata_t buf, uint32 x, uint32 y, uint32 z, tsample_t s)
  286. {
  287. if (!TIFFCheckTile(tif, x, y, z, s))
  288. return (-1);
  289. /*
  290. * NB: A tile size of -1 is used instead of tif_tilesize knowing
  291. * that TIFFWriteEncodedTile will clamp this to the tile size.
  292. * This is done because the tile size may not be defined until
  293. * after the output buffer is setup in TIFFWriteBufferSetup.
  294. */
  295. return (TIFFWriteEncodedTile(tif,
  296. TIFFComputeTile(tif, x, y, z, s), buf, (tsize_t) -1));
  297. }
  298. /*
  299. * Encode the supplied data and write it to the
  300. * specified tile. There must be space for the
  301. * data. The function clamps individual writes
  302. * to a tile to the tile size, but does not (and
  303. * can not) check that multiple writes to the same
  304. * tile do not write more than tile size data.
  305. *
  306. * NB: Image length must be setup before writing; this
  307. * interface does not support automatically growing
  308. * the image on each write (as TIFFWriteScanline does).
  309. */
  310. tsize_t
  311. TIFFWriteEncodedTile(TIFF* tif, ttile_t tile, tdata_t data, tsize_t cc)
  312. {
  313. static const char module[] = "TIFFWriteEncodedTile";
  314. TIFFDirectory *td;
  315. tsample_t sample;
  316. if (!WRITECHECKTILES(tif, module))
  317. return ((tsize_t) -1);
  318. td = &tif->tif_dir;
  319. if (tile >= td->td_nstrips) {
  320. TIFFErrorExt(tif->tif_clientdata, module, "%s: Tile %lu out of range, max %lu",
  321. tif->tif_name, (unsigned long) tile, (unsigned long) td->td_nstrips);
  322. return ((tsize_t) -1);
  323. }
  324. /*
  325. * Handle delayed allocation of data buffer. This
  326. * permits it to be sized more intelligently (using
  327. * directory information).
  328. */
  329. if (!BUFFERCHECK(tif))
  330. return ((tsize_t) -1);
  331. tif->tif_curtile = tile;
  332. tif->tif_rawcc = 0;
  333. tif->tif_rawcp = tif->tif_rawdata;
  334. if( td->td_stripbytecount[tile] > 0 )
  335. {
  336. /* Force TIFFAppendToStrip() to consider placing data at end
  337. of file. */
  338. tif->tif_curoff = 0;
  339. }
  340. /*
  341. * Compute tiles per row & per column to compute
  342. * current row and column
  343. */
  344. tif->tif_row = (tile % TIFFhowmany(td->td_imagelength, td->td_tilelength))
  345. * td->td_tilelength;
  346. tif->tif_col = (tile % TIFFhowmany(td->td_imagewidth, td->td_tilewidth))
  347. * td->td_tilewidth;
  348. if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
  349. if (!(*tif->tif_setupencode)(tif))
  350. return ((tsize_t) -1);
  351. tif->tif_flags |= TIFF_CODERSETUP;
  352. }
  353. tif->tif_flags &= ~TIFF_POSTENCODE;
  354. sample = (tsample_t)(tile/td->td_stripsperimage);
  355. if (!(*tif->tif_preencode)(tif, sample))
  356. return ((tsize_t) -1);
  357. /*
  358. * Clamp write amount to the tile size. This is mostly
  359. * done so that callers can pass in some large number
  360. * (e.g. -1) and have the tile size used instead.
  361. */
  362. if ( cc < 1 || cc > tif->tif_tilesize)
  363. cc = tif->tif_tilesize;
  364. /* swab if needed - note that source buffer will be altered */
  365. tif->tif_postdecode( tif, (tidata_t) data, cc );
  366. if (!(*tif->tif_encodetile)(tif, (tidata_t) data, cc, sample))
  367. return ((tsize_t) 0);
  368. if (!(*tif->tif_postencode)(tif))
  369. return ((tsize_t) -1);
  370. if (!isFillOrder(tif, td->td_fillorder) &&
  371. (tif->tif_flags & TIFF_NOBITREV) == 0)
  372. TIFFReverseBits((unsigned char *)tif->tif_rawdata, tif->tif_rawcc);
  373. if (tif->tif_rawcc > 0 && !TIFFAppendToStrip(tif, tile,
  374. tif->tif_rawdata, tif->tif_rawcc))
  375. return ((tsize_t) -1);
  376. tif->tif_rawcc = 0;
  377. tif->tif_rawcp = tif->tif_rawdata;
  378. return (cc);
  379. }
  380. /*
  381. * Write the supplied data to the specified strip.
  382. * There must be space for the data; we don't check
  383. * if strips overlap!
  384. *
  385. * NB: Image length must be setup before writing; this
  386. * interface does not support automatically growing
  387. * the image on each write (as TIFFWriteScanline does).
  388. */
  389. tsize_t
  390. TIFFWriteRawTile(TIFF* tif, ttile_t tile, tdata_t data, tsize_t cc)
  391. {
  392. static const char module[] = "TIFFWriteRawTile";
  393. if (!WRITECHECKTILES(tif, module))
  394. return ((tsize_t) -1);
  395. if (tile >= tif->tif_dir.td_nstrips) {
  396. TIFFErrorExt(tif->tif_clientdata, module, "%s: Tile %lu out of range, max %lu",
  397. tif->tif_name, (unsigned long) tile,
  398. (unsigned long) tif->tif_dir.td_nstrips);
  399. return ((tsize_t) -1);
  400. }
  401. return (TIFFAppendToStrip(tif, tile, (tidata_t) data, cc) ?
  402. cc : (tsize_t) -1);
  403. }
  404. #define isUnspecified(tif, f) \
  405. (TIFFFieldSet(tif,f) && (tif)->tif_dir.td_imagelength == 0)
  406. int
  407. TIFFSetupStrips(TIFF* tif)
  408. {
  409. TIFFDirectory* td = &tif->tif_dir;
  410. if (isTiled(tif))
  411. td->td_stripsperimage =
  412. isUnspecified(tif, FIELD_TILEDIMENSIONS) ?
  413. td->td_samplesperpixel : TIFFNumberOfTiles(tif);
  414. else
  415. td->td_stripsperimage =
  416. isUnspecified(tif, FIELD_ROWSPERSTRIP) ?
  417. td->td_samplesperpixel : TIFFNumberOfStrips(tif);
  418. td->td_nstrips = td->td_stripsperimage;
  419. if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
  420. td->td_stripsperimage /= td->td_samplesperpixel;
  421. td->td_stripoffset = (uint32 *)
  422. _TIFFmalloc(td->td_nstrips * sizeof (uint32));
  423. td->td_stripbytecount = (uint32 *)
  424. _TIFFmalloc(td->td_nstrips * sizeof (uint32));
  425. if (td->td_stripoffset == NULL || td->td_stripbytecount == NULL)
  426. return (0);
  427. /*
  428. * Place data at the end-of-file
  429. * (by setting offsets to zero).
  430. */
  431. _TIFFmemset(td->td_stripoffset, 0, td->td_nstrips*sizeof (uint32));
  432. _TIFFmemset(td->td_stripbytecount, 0, td->td_nstrips*sizeof (uint32));
  433. TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS);
  434. TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS);
  435. return (1);
  436. }
  437. #undef isUnspecified
  438. /*
  439. * Verify file is writable and that the directory
  440. * information is setup properly. In doing the latter
  441. * we also "freeze" the state of the directory so
  442. * that important information is not changed.
  443. */
  444. int
  445. TIFFWriteCheck(TIFF* tif, int tiles, const char* module)
  446. {
  447. if (tif->tif_mode == O_RDONLY) {
  448. TIFFErrorExt(tif->tif_clientdata, module, "%s: File not open for writing",
  449. tif->tif_name);
  450. return (0);
  451. }
  452. if (tiles ^ isTiled(tif)) {
  453. TIFFErrorExt(tif->tif_clientdata, tif->tif_name, tiles ?
  454. "Can not write tiles to a stripped image" :
  455. "Can not write scanlines to a tiled image");
  456. return (0);
  457. }
  458. /*
  459. * On the first write verify all the required information
  460. * has been setup and initialize any data structures that
  461. * had to wait until directory information was set.
  462. * Note that a lot of our work is assumed to remain valid
  463. * because we disallow any of the important parameters
  464. * from changing after we start writing (i.e. once
  465. * TIFF_BEENWRITING is set, TIFFSetField will only allow
  466. * the image's length to be changed).
  467. */
  468. if (!TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS)) {
  469. TIFFErrorExt(tif->tif_clientdata, module,
  470. "%s: Must set \"ImageWidth\" before writing data",
  471. tif->tif_name);
  472. return (0);
  473. }
  474. if (tif->tif_dir.td_samplesperpixel == 1) {
  475. /*
  476. * Planarconfiguration is irrelevant in case of single band
  477. * images and need not be included. We will set it anyway,
  478. * because this field is used in other parts of library even
  479. * in the single band case.
  480. */
  481. if (!TIFFFieldSet(tif, FIELD_PLANARCONFIG))
  482. tif->tif_dir.td_planarconfig = PLANARCONFIG_CONTIG;
  483. } else {
  484. if (!TIFFFieldSet(tif, FIELD_PLANARCONFIG)) {
  485. TIFFErrorExt(tif->tif_clientdata, module,
  486. "%s: Must set \"PlanarConfiguration\" before writing data",
  487. tif->tif_name);
  488. return (0);
  489. }
  490. }
  491. if (tif->tif_dir.td_stripoffset == NULL && !TIFFSetupStrips(tif)) {
  492. tif->tif_dir.td_nstrips = 0;
  493. TIFFErrorExt(tif->tif_clientdata, module, "%s: No space for %s arrays",
  494. tif->tif_name, isTiled(tif) ? "tile" : "strip");
  495. return (0);
  496. }
  497. tif->tif_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tsize_t) -1;
  498. tif->tif_scanlinesize = TIFFScanlineSize(tif);
  499. tif->tif_flags |= TIFF_BEENWRITING;
  500. return (1);
  501. }
  502. /*
  503. * Setup the raw data buffer used for encoding.
  504. */
  505. int
  506. TIFFWriteBufferSetup(TIFF* tif, tdata_t bp, tsize_t size)
  507. {
  508. static const char module[] = "TIFFWriteBufferSetup";
  509. if (tif->tif_rawdata) {
  510. if (tif->tif_flags & TIFF_MYBUFFER) {
  511. _TIFFfree(tif->tif_rawdata);
  512. tif->tif_flags &= ~TIFF_MYBUFFER;
  513. }
  514. tif->tif_rawdata = NULL;
  515. }
  516. if (size == (tsize_t) -1) {
  517. size = (isTiled(tif) ?
  518. tif->tif_tilesize : TIFFStripSize(tif));
  519. /*
  520. * Make raw data buffer at least 8K
  521. */
  522. if (size < 8*1024)
  523. size = 8*1024;
  524. bp = NULL; /* NB: force malloc */
  525. }
  526. if (bp == NULL) {
  527. bp = _TIFFmalloc(size);
  528. if (bp == NULL) {
  529. TIFFErrorExt(tif->tif_clientdata, module, "%s: No space for output buffer",
  530. tif->tif_name);
  531. return (0);
  532. }
  533. tif->tif_flags |= TIFF_MYBUFFER;
  534. } else
  535. tif->tif_flags &= ~TIFF_MYBUFFER;
  536. tif->tif_rawdata = (tidata_t) bp;
  537. tif->tif_rawdatasize = size;
  538. tif->tif_rawcc = 0;
  539. tif->tif_rawcp = tif->tif_rawdata;
  540. tif->tif_flags |= TIFF_BUFFERSETUP;
  541. return (1);
  542. }
  543. /*
  544. * Grow the strip data structures by delta strips.
  545. */
  546. static int
  547. TIFFGrowStrips(TIFF* tif, int delta, const char* module)
  548. {
  549. TIFFDirectory *td = &tif->tif_dir;
  550. uint32 *new_stripoffset, *new_stripbytecount;
  551. assert(td->td_planarconfig == PLANARCONFIG_CONTIG);
  552. new_stripoffset = (uint32*)_TIFFrealloc(td->td_stripoffset,
  553. (td->td_nstrips + delta) * sizeof (uint32));
  554. new_stripbytecount = (uint32*)_TIFFrealloc(td->td_stripbytecount,
  555. (td->td_nstrips + delta) * sizeof (uint32));
  556. if (new_stripoffset == NULL || new_stripbytecount == NULL) {
  557. if (new_stripoffset)
  558. _TIFFfree(new_stripoffset);
  559. if (new_stripbytecount)
  560. _TIFFfree(new_stripbytecount);
  561. td->td_nstrips = 0;
  562. TIFFErrorExt(tif->tif_clientdata, module, "%s: No space to expand strip arrays",
  563. tif->tif_name);
  564. return (0);
  565. }
  566. td->td_stripoffset = new_stripoffset;
  567. td->td_stripbytecount = new_stripbytecount;
  568. _TIFFmemset(td->td_stripoffset + td->td_nstrips,
  569. 0, delta*sizeof (uint32));
  570. _TIFFmemset(td->td_stripbytecount + td->td_nstrips,
  571. 0, delta*sizeof (uint32));
  572. td->td_nstrips += delta;
  573. return (1);
  574. }
  575. /*
  576. * Append the data to the specified strip.
  577. */
  578. static int
  579. TIFFAppendToStrip(TIFF* tif, tstrip_t strip, tidata_t data, tsize_t cc)
  580. {
  581. static const char module[] = "TIFFAppendToStrip";
  582. TIFFDirectory *td = &tif->tif_dir;
  583. if (td->td_stripoffset[strip] == 0 || tif->tif_curoff == 0) {
  584. assert(td->td_nstrips > 0);
  585. if( td->td_stripbytecount[strip] != 0
  586. && td->td_stripoffset[strip] != 0
  587. && td->td_stripbytecount[strip] >= cc )
  588. {
  589. /*
  590. * There is already tile data on disk, and the new tile
  591. * data we have to will fit in the same space. The only
  592. * aspect of this that is risky is that there could be
  593. * more data to append to this strip before we are done
  594. * depending on how we are getting called.
  595. */
  596. if (!SeekOK(tif, td->td_stripoffset[strip])) {
  597. TIFFErrorExt(tif->tif_clientdata, module,
  598. "Seek error at scanline %lu",
  599. (unsigned long)tif->tif_row);
  600. return (0);
  601. }
  602. }
  603. else
  604. {
  605. /*
  606. * Seek to end of file, and set that as our location to
  607. * write this strip.
  608. */
  609. td->td_stripoffset[strip] = TIFFSeekFile(tif, 0, SEEK_END);
  610. }
  611. tif->tif_curoff = td->td_stripoffset[strip];
  612. /*
  613. * We are starting a fresh strip/tile, so set the size to zero.
  614. */
  615. td->td_stripbytecount[strip] = 0;
  616. }
  617. if (!WriteOK(tif, data, cc)) {
  618. TIFFErrorExt(tif->tif_clientdata, module, "Write error at scanline %lu",
  619. (unsigned long) tif->tif_row);
  620. return (0);
  621. }
  622. tif->tif_curoff = tif->tif_curoff+cc;
  623. td->td_stripbytecount[strip] += cc;
  624. return (1);
  625. }
  626. /*
  627. * Internal version of TIFFFlushData that can be
  628. * called by ``encodestrip routines'' w/o concern
  629. * for infinite recursion.
  630. */
  631. int
  632. TIFFFlushData1(TIFF* tif)
  633. {
  634. if (tif->tif_rawcc > 0) {
  635. if (!isFillOrder(tif, tif->tif_dir.td_fillorder) &&
  636. (tif->tif_flags & TIFF_NOBITREV) == 0)
  637. TIFFReverseBits((unsigned char *)tif->tif_rawdata,
  638. tif->tif_rawcc);
  639. if (!TIFFAppendToStrip(tif,
  640. isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip,
  641. tif->tif_rawdata, tif->tif_rawcc))
  642. return (0);
  643. tif->tif_rawcc = 0;
  644. tif->tif_rawcp = tif->tif_rawdata;
  645. }
  646. return (1);
  647. }
  648. /*
  649. * Set the current write offset. This should only be
  650. * used to set the offset to a known previous location
  651. * (very carefully), or to 0 so that the next write gets
  652. * appended to the end of the file.
  653. */
  654. void
  655. TIFFSetWriteOffset(TIFF* tif, toff_t off)
  656. {
  657. tif->tif_curoff = off;
  658. }
  659. /* vim: set ts=8 sts=8 sw=8 noet: */
  660. /*
  661. * Local Variables:
  662. * mode: c
  663. * c-basic-offset: 8
  664. * fill-column: 78
  665. * End:
  666. */