tif_write.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749
  1. /* $Id: tif_write.c,v 1.36 2011-02-18 20:53:04 fwarmerdam 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, (tmsize_t) -1))
  40. static int TIFFGrowStrips(TIFF* tif, uint32 delta, const char* module);
  41. static int TIFFAppendToStrip(TIFF* tif, uint32 strip, uint8* data, tmsize_t cc);
  42. int
  43. TIFFWriteScanline(TIFF* tif, void* buf, uint32 row, uint16 sample)
  44. {
  45. static const char module[] = "TIFFWriteScanline";
  46. register TIFFDirectory *td;
  47. int status, imagegrew = 0;
  48. uint32 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. tif->tif_flags |= TIFF_BUF4WRITE; /* not strictly sure this is right*/
  59. td = &tif->tif_dir;
  60. /*
  61. * Extend image length if needed
  62. * (but only for PlanarConfig=1).
  63. */
  64. if (row >= td->td_imagelength) { /* extend image */
  65. if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
  66. TIFFErrorExt(tif->tif_clientdata, module,
  67. "Can not change \"ImageLength\" when using separate planes");
  68. return (-1);
  69. }
  70. td->td_imagelength = row+1;
  71. imagegrew = 1;
  72. }
  73. /*
  74. * Calculate strip and check for crossings.
  75. */
  76. if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
  77. if (sample >= td->td_samplesperpixel) {
  78. TIFFErrorExt(tif->tif_clientdata, module,
  79. "%lu: Sample out of range, max %lu",
  80. (unsigned long) sample, (unsigned long) td->td_samplesperpixel);
  81. return (-1);
  82. }
  83. strip = sample*td->td_stripsperimage + row/td->td_rowsperstrip;
  84. } else
  85. strip = row / td->td_rowsperstrip;
  86. /*
  87. * Check strip array to make sure there's space. We don't support
  88. * dynamically growing files that have data organized in separate
  89. * bitplanes because it's too painful. In that case we require that
  90. * the imagelength be set properly before the first write (so that the
  91. * strips array will be fully allocated above).
  92. */
  93. if (strip >= td->td_nstrips && !TIFFGrowStrips(tif, 1, module))
  94. return (-1);
  95. if (strip != tif->tif_curstrip) {
  96. /*
  97. * Changing strips -- flush any data present.
  98. */
  99. if (!TIFFFlushData(tif))
  100. return (-1);
  101. tif->tif_curstrip = strip;
  102. /*
  103. * Watch out for a growing image. The value of strips/image
  104. * will initially be 1 (since it can't be deduced until the
  105. * imagelength is known).
  106. */
  107. if (strip >= td->td_stripsperimage && imagegrew)
  108. td->td_stripsperimage =
  109. TIFFhowmany_32(td->td_imagelength,td->td_rowsperstrip);
  110. tif->tif_row =
  111. (strip % td->td_stripsperimage) * td->td_rowsperstrip;
  112. if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
  113. if (!(*tif->tif_setupencode)(tif))
  114. return (-1);
  115. tif->tif_flags |= TIFF_CODERSETUP;
  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, (uint8*) buf, tif->tif_scanlinesize );
  155. status = (*tif->tif_encoderow)(tif, (uint8*) 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. tmsize_t
  168. TIFFWriteEncodedStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc)
  169. {
  170. static const char module[] = "TIFFWriteEncodedStrip";
  171. TIFFDirectory *td = &tif->tif_dir;
  172. uint16 sample;
  173. if (!WRITECHECKSTRIPS(tif, module))
  174. return ((tmsize_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, module,
  187. "Can not grow image by strips when using separate planes");
  188. return ((tmsize_t) -1);
  189. }
  190. if (!TIFFGrowStrips(tif, 1, module))
  191. return ((tmsize_t) -1);
  192. td->td_stripsperimage =
  193. TIFFhowmany_32(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 ((tmsize_t) -1);
  202. tif->tif_flags |= TIFF_BUF4WRITE;
  203. tif->tif_curstrip = strip;
  204. tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
  205. if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
  206. if (!(*tif->tif_setupencode)(tif))
  207. return ((tmsize_t) -1);
  208. tif->tif_flags |= TIFF_CODERSETUP;
  209. }
  210. tif->tif_rawcc = 0;
  211. tif->tif_rawcp = tif->tif_rawdata;
  212. if( td->td_stripbytecount[strip] > 0 )
  213. {
  214. /* Force TIFFAppendToStrip() to consider placing data at end
  215. of file. */
  216. tif->tif_curoff = 0;
  217. }
  218. tif->tif_flags &= ~TIFF_POSTENCODE;
  219. sample = (uint16)(strip / td->td_stripsperimage);
  220. if (!(*tif->tif_preencode)(tif, sample))
  221. return ((tmsize_t) -1);
  222. /* swab if needed - note that source buffer will be altered */
  223. tif->tif_postdecode( tif, (uint8*) data, cc );
  224. if (!(*tif->tif_encodestrip)(tif, (uint8*) data, cc, sample))
  225. return (0);
  226. if (!(*tif->tif_postencode)(tif))
  227. return ((tmsize_t) -1);
  228. if (!isFillOrder(tif, td->td_fillorder) &&
  229. (tif->tif_flags & TIFF_NOBITREV) == 0)
  230. TIFFReverseBits(tif->tif_rawdata, tif->tif_rawcc);
  231. if (tif->tif_rawcc > 0 &&
  232. !TIFFAppendToStrip(tif, strip, tif->tif_rawdata, tif->tif_rawcc))
  233. return ((tmsize_t) -1);
  234. tif->tif_rawcc = 0;
  235. tif->tif_rawcp = tif->tif_rawdata;
  236. return (cc);
  237. }
  238. /*
  239. * Write the supplied data to the specified strip.
  240. *
  241. * NB: Image length must be setup before writing.
  242. */
  243. tmsize_t
  244. TIFFWriteRawStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc)
  245. {
  246. static const char module[] = "TIFFWriteRawStrip";
  247. TIFFDirectory *td = &tif->tif_dir;
  248. if (!WRITECHECKSTRIPS(tif, module))
  249. return ((tmsize_t) -1);
  250. /*
  251. * Check strip array to make sure there's space.
  252. * We don't support dynamically growing files that
  253. * have data organized in separate bitplanes because
  254. * it's too painful. In that case we require that
  255. * the imagelength be set properly before the first
  256. * write (so that the strips array will be fully
  257. * allocated above).
  258. */
  259. if (strip >= td->td_nstrips) {
  260. if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
  261. TIFFErrorExt(tif->tif_clientdata, module,
  262. "Can not grow image by strips when using separate planes");
  263. return ((tmsize_t) -1);
  264. }
  265. /*
  266. * Watch out for a growing image. The value of
  267. * strips/image will initially be 1 (since it
  268. * can't be deduced until the imagelength is known).
  269. */
  270. if (strip >= td->td_stripsperimage)
  271. td->td_stripsperimage =
  272. TIFFhowmany_32(td->td_imagelength,td->td_rowsperstrip);
  273. if (!TIFFGrowStrips(tif, 1, module))
  274. return ((tmsize_t) -1);
  275. }
  276. tif->tif_curstrip = strip;
  277. tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
  278. return (TIFFAppendToStrip(tif, strip, (uint8*) data, cc) ?
  279. cc : (tmsize_t) -1);
  280. }
  281. /*
  282. * Write and compress a tile of data. The
  283. * tile is selected by the (x,y,z,s) coordinates.
  284. */
  285. tmsize_t
  286. TIFFWriteTile(TIFF* tif, void* buf, uint32 x, uint32 y, uint32 z, uint16 s)
  287. {
  288. if (!TIFFCheckTile(tif, x, y, z, s))
  289. return ((tmsize_t)(-1));
  290. /*
  291. * NB: A tile size of -1 is used instead of tif_tilesize knowing
  292. * that TIFFWriteEncodedTile will clamp this to the tile size.
  293. * This is done because the tile size may not be defined until
  294. * after the output buffer is setup in TIFFWriteBufferSetup.
  295. */
  296. return (TIFFWriteEncodedTile(tif,
  297. TIFFComputeTile(tif, x, y, z, s), buf, (tmsize_t)(-1)));
  298. }
  299. /*
  300. * Encode the supplied data and write it to the
  301. * specified tile. There must be space for the
  302. * data. The function clamps individual writes
  303. * to a tile to the tile size, but does not (and
  304. * can not) check that multiple writes to the same
  305. * tile do not write more than tile size data.
  306. *
  307. * NB: Image length must be setup before writing; this
  308. * interface does not support automatically growing
  309. * the image on each write (as TIFFWriteScanline does).
  310. */
  311. tmsize_t
  312. TIFFWriteEncodedTile(TIFF* tif, uint32 tile, void* data, tmsize_t cc)
  313. {
  314. static const char module[] = "TIFFWriteEncodedTile";
  315. TIFFDirectory *td;
  316. uint16 sample;
  317. if (!WRITECHECKTILES(tif, module))
  318. return ((tmsize_t)(-1));
  319. td = &tif->tif_dir;
  320. if (tile >= td->td_nstrips) {
  321. TIFFErrorExt(tif->tif_clientdata, module, "Tile %lu out of range, max %lu",
  322. (unsigned long) tile, (unsigned long) td->td_nstrips);
  323. return ((tmsize_t)(-1));
  324. }
  325. /*
  326. * Handle delayed allocation of data buffer. This
  327. * permits it to be sized more intelligently (using
  328. * directory information).
  329. */
  330. if (!BUFFERCHECK(tif))
  331. return ((tmsize_t)(-1));
  332. tif->tif_flags |= TIFF_BUF4WRITE;
  333. tif->tif_curtile = tile;
  334. tif->tif_rawcc = 0;
  335. tif->tif_rawcp = tif->tif_rawdata;
  336. if( td->td_stripbytecount[tile] > 0 )
  337. {
  338. /* Force TIFFAppendToStrip() to consider placing data at end
  339. of file. */
  340. tif->tif_curoff = 0;
  341. }
  342. /*
  343. * Compute tiles per row & per column to compute
  344. * current row and column
  345. */
  346. tif->tif_row = (tile % TIFFhowmany_32(td->td_imagelength, td->td_tilelength))
  347. * td->td_tilelength;
  348. tif->tif_col = (tile % TIFFhowmany_32(td->td_imagewidth, td->td_tilewidth))
  349. * td->td_tilewidth;
  350. if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
  351. if (!(*tif->tif_setupencode)(tif))
  352. return ((tmsize_t)(-1));
  353. tif->tif_flags |= TIFF_CODERSETUP;
  354. }
  355. tif->tif_flags &= ~TIFF_POSTENCODE;
  356. sample = (uint16)(tile/td->td_stripsperimage);
  357. if (!(*tif->tif_preencode)(tif, sample))
  358. return ((tmsize_t)(-1));
  359. /*
  360. * Clamp write amount to the tile size. This is mostly
  361. * done so that callers can pass in some large number
  362. * (e.g. -1) and have the tile size used instead.
  363. */
  364. if ( cc < 1 || cc > tif->tif_tilesize)
  365. cc = tif->tif_tilesize;
  366. /* swab if needed - note that source buffer will be altered */
  367. tif->tif_postdecode( tif, (uint8*) data, cc );
  368. if (!(*tif->tif_encodetile)(tif, (uint8*) data, cc, sample))
  369. return (0);
  370. if (!(*tif->tif_postencode)(tif))
  371. return ((tmsize_t)(-1));
  372. if (!isFillOrder(tif, td->td_fillorder) &&
  373. (tif->tif_flags & TIFF_NOBITREV) == 0)
  374. TIFFReverseBits((uint8*)tif->tif_rawdata, tif->tif_rawcc);
  375. if (tif->tif_rawcc > 0 && !TIFFAppendToStrip(tif, tile,
  376. tif->tif_rawdata, tif->tif_rawcc))
  377. return ((tmsize_t)(-1));
  378. tif->tif_rawcc = 0;
  379. tif->tif_rawcp = tif->tif_rawdata;
  380. return (cc);
  381. }
  382. /*
  383. * Write the supplied data to the specified strip.
  384. * There must be space for the data; we don't check
  385. * if strips overlap!
  386. *
  387. * NB: Image length must be setup before writing; this
  388. * interface does not support automatically growing
  389. * the image on each write (as TIFFWriteScanline does).
  390. */
  391. tmsize_t
  392. TIFFWriteRawTile(TIFF* tif, uint32 tile, void* data, tmsize_t cc)
  393. {
  394. static const char module[] = "TIFFWriteRawTile";
  395. if (!WRITECHECKTILES(tif, module))
  396. return ((tmsize_t)(-1));
  397. if (tile >= tif->tif_dir.td_nstrips) {
  398. TIFFErrorExt(tif->tif_clientdata, module, "Tile %lu out of range, max %lu",
  399. (unsigned long) tile,
  400. (unsigned long) tif->tif_dir.td_nstrips);
  401. return ((tmsize_t)(-1));
  402. }
  403. return (TIFFAppendToStrip(tif, tile, (uint8*) data, cc) ?
  404. cc : (tmsize_t)(-1));
  405. }
  406. #define isUnspecified(tif, f) \
  407. (TIFFFieldSet(tif,f) && (tif)->tif_dir.td_imagelength == 0)
  408. int
  409. TIFFSetupStrips(TIFF* tif)
  410. {
  411. TIFFDirectory* td = &tif->tif_dir;
  412. if (isTiled(tif))
  413. td->td_stripsperimage =
  414. isUnspecified(tif, FIELD_TILEDIMENSIONS) ?
  415. td->td_samplesperpixel : TIFFNumberOfTiles(tif);
  416. else
  417. td->td_stripsperimage =
  418. isUnspecified(tif, FIELD_ROWSPERSTRIP) ?
  419. td->td_samplesperpixel : TIFFNumberOfStrips(tif);
  420. td->td_nstrips = td->td_stripsperimage;
  421. if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
  422. td->td_stripsperimage /= td->td_samplesperpixel;
  423. td->td_stripoffset = (uint64 *)
  424. _TIFFmalloc(td->td_nstrips * sizeof (uint64));
  425. td->td_stripbytecount = (uint64 *)
  426. _TIFFmalloc(td->td_nstrips * sizeof (uint64));
  427. if (td->td_stripoffset == NULL || td->td_stripbytecount == NULL)
  428. return (0);
  429. /*
  430. * Place data at the end-of-file
  431. * (by setting offsets to zero).
  432. */
  433. _TIFFmemset(td->td_stripoffset, 0, td->td_nstrips*sizeof (uint64));
  434. _TIFFmemset(td->td_stripbytecount, 0, td->td_nstrips*sizeof (uint64));
  435. TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS);
  436. TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS);
  437. return (1);
  438. }
  439. #undef isUnspecified
  440. /*
  441. * Verify file is writable and that the directory
  442. * information is setup properly. In doing the latter
  443. * we also "freeze" the state of the directory so
  444. * that important information is not changed.
  445. */
  446. int
  447. TIFFWriteCheck(TIFF* tif, int tiles, const char* module)
  448. {
  449. if (tif->tif_mode == O_RDONLY) {
  450. TIFFErrorExt(tif->tif_clientdata, module, "File not open for writing");
  451. return (0);
  452. }
  453. if (tiles ^ isTiled(tif)) {
  454. TIFFErrorExt(tif->tif_clientdata, module, tiles ?
  455. "Can not write tiles to a stripped image" :
  456. "Can not write scanlines to a tiled image");
  457. return (0);
  458. }
  459. _TIFFFillStriles( tif );
  460. /*
  461. * On the first write verify all the required information
  462. * has been setup and initialize any data structures that
  463. * had to wait until directory information was set.
  464. * Note that a lot of our work is assumed to remain valid
  465. * because we disallow any of the important parameters
  466. * from changing after we start writing (i.e. once
  467. * TIFF_BEENWRITING is set, TIFFSetField will only allow
  468. * the image's length to be changed).
  469. */
  470. if (!TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS)) {
  471. TIFFErrorExt(tif->tif_clientdata, module,
  472. "Must set \"ImageWidth\" before writing data");
  473. return (0);
  474. }
  475. if (tif->tif_dir.td_samplesperpixel == 1) {
  476. /*
  477. * Planarconfiguration is irrelevant in case of single band
  478. * images and need not be included. We will set it anyway,
  479. * because this field is used in other parts of library even
  480. * in the single band case.
  481. */
  482. if (!TIFFFieldSet(tif, FIELD_PLANARCONFIG))
  483. tif->tif_dir.td_planarconfig = PLANARCONFIG_CONTIG;
  484. } else {
  485. if (!TIFFFieldSet(tif, FIELD_PLANARCONFIG)) {
  486. TIFFErrorExt(tif->tif_clientdata, module,
  487. "Must set \"PlanarConfiguration\" before writing data");
  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, "No space for %s arrays",
  494. isTiled(tif) ? "tile" : "strip");
  495. return (0);
  496. }
  497. if (isTiled(tif))
  498. {
  499. tif->tif_tilesize = TIFFTileSize(tif);
  500. if (tif->tif_tilesize == 0)
  501. return (0);
  502. }
  503. else
  504. tif->tif_tilesize = (tmsize_t)(-1);
  505. tif->tif_scanlinesize = TIFFScanlineSize(tif);
  506. if (tif->tif_scanlinesize == 0)
  507. return (0);
  508. tif->tif_flags |= TIFF_BEENWRITING;
  509. return (1);
  510. }
  511. /*
  512. * Setup the raw data buffer used for encoding.
  513. */
  514. int
  515. TIFFWriteBufferSetup(TIFF* tif, void* bp, tmsize_t size)
  516. {
  517. static const char module[] = "TIFFWriteBufferSetup";
  518. if (tif->tif_rawdata) {
  519. if (tif->tif_flags & TIFF_MYBUFFER) {
  520. _TIFFfree(tif->tif_rawdata);
  521. tif->tif_flags &= ~TIFF_MYBUFFER;
  522. }
  523. tif->tif_rawdata = NULL;
  524. }
  525. if (size == (tmsize_t)(-1)) {
  526. size = (isTiled(tif) ?
  527. tif->tif_tilesize : TIFFStripSize(tif));
  528. /*
  529. * Make raw data buffer at least 8K
  530. */
  531. if (size < 8*1024)
  532. size = 8*1024;
  533. bp = NULL; /* NB: force malloc */
  534. }
  535. if (bp == NULL) {
  536. bp = _TIFFmalloc(size);
  537. if (bp == NULL) {
  538. TIFFErrorExt(tif->tif_clientdata, module, "No space for output buffer");
  539. return (0);
  540. }
  541. tif->tif_flags |= TIFF_MYBUFFER;
  542. } else
  543. tif->tif_flags &= ~TIFF_MYBUFFER;
  544. tif->tif_rawdata = (uint8*) bp;
  545. tif->tif_rawdatasize = size;
  546. tif->tif_rawcc = 0;
  547. tif->tif_rawcp = tif->tif_rawdata;
  548. tif->tif_flags |= TIFF_BUFFERSETUP;
  549. return (1);
  550. }
  551. /*
  552. * Grow the strip data structures by delta strips.
  553. */
  554. static int
  555. TIFFGrowStrips(TIFF* tif, uint32 delta, const char* module)
  556. {
  557. TIFFDirectory *td = &tif->tif_dir;
  558. uint64* new_stripoffset;
  559. uint64* new_stripbytecount;
  560. assert(td->td_planarconfig == PLANARCONFIG_CONTIG);
  561. new_stripoffset = (uint64*)_TIFFrealloc(td->td_stripoffset,
  562. (td->td_nstrips + delta) * sizeof (uint64));
  563. new_stripbytecount = (uint64*)_TIFFrealloc(td->td_stripbytecount,
  564. (td->td_nstrips + delta) * sizeof (uint64));
  565. if (new_stripoffset == NULL || new_stripbytecount == NULL) {
  566. if (new_stripoffset)
  567. _TIFFfree(new_stripoffset);
  568. if (new_stripbytecount)
  569. _TIFFfree(new_stripbytecount);
  570. td->td_nstrips = 0;
  571. TIFFErrorExt(tif->tif_clientdata, module, "No space to expand strip arrays");
  572. return (0);
  573. }
  574. td->td_stripoffset = new_stripoffset;
  575. td->td_stripbytecount = new_stripbytecount;
  576. _TIFFmemset(td->td_stripoffset + td->td_nstrips,
  577. 0, delta*sizeof (uint64));
  578. _TIFFmemset(td->td_stripbytecount + td->td_nstrips,
  579. 0, delta*sizeof (uint64));
  580. td->td_nstrips += delta;
  581. tif->tif_flags |= TIFF_DIRTYDIRECT;
  582. return (1);
  583. }
  584. /*
  585. * Append the data to the specified strip.
  586. */
  587. static int
  588. TIFFAppendToStrip(TIFF* tif, uint32 strip, uint8* data, tmsize_t cc)
  589. {
  590. static const char module[] = "TIFFAppendToStrip";
  591. TIFFDirectory *td = &tif->tif_dir;
  592. uint64 m;
  593. int64 old_byte_count = -1;
  594. if (td->td_stripoffset[strip] == 0 || tif->tif_curoff == 0) {
  595. assert(td->td_nstrips > 0);
  596. if( td->td_stripbytecount[strip] != 0
  597. && td->td_stripoffset[strip] != 0
  598. && td->td_stripbytecount[strip] >= (uint64) cc )
  599. {
  600. /*
  601. * There is already tile data on disk, and the new tile
  602. * data we have will fit in the same space. The only
  603. * aspect of this that is risky is that there could be
  604. * more data to append to this strip before we are done
  605. * depending on how we are getting called.
  606. */
  607. if (!SeekOK(tif, td->td_stripoffset[strip])) {
  608. TIFFErrorExt(tif->tif_clientdata, module,
  609. "Seek error at scanline %lu",
  610. (unsigned long)tif->tif_row);
  611. return (0);
  612. }
  613. }
  614. else
  615. {
  616. /*
  617. * Seek to end of file, and set that as our location to
  618. * write this strip.
  619. */
  620. td->td_stripoffset[strip] = TIFFSeekFile(tif, 0, SEEK_END);
  621. tif->tif_flags |= TIFF_DIRTYSTRIP;
  622. }
  623. tif->tif_curoff = td->td_stripoffset[strip];
  624. /*
  625. * We are starting a fresh strip/tile, so set the size to zero.
  626. */
  627. old_byte_count = td->td_stripbytecount[strip];
  628. td->td_stripbytecount[strip] = 0;
  629. }
  630. m = tif->tif_curoff+cc;
  631. if (!(tif->tif_flags&TIFF_BIGTIFF))
  632. m = (uint32)m;
  633. if ((m<tif->tif_curoff)||(m<(uint64)cc))
  634. {
  635. TIFFErrorExt(tif->tif_clientdata, module, "Maximum TIFF file size exceeded");
  636. return (0);
  637. }
  638. if (!WriteOK(tif, data, cc)) {
  639. TIFFErrorExt(tif->tif_clientdata, module, "Write error at scanline %lu",
  640. (unsigned long) tif->tif_row);
  641. return (0);
  642. }
  643. tif->tif_curoff = m;
  644. td->td_stripbytecount[strip] += cc;
  645. if( (int64) td->td_stripbytecount[strip] != old_byte_count )
  646. tif->tif_flags |= TIFF_DIRTYSTRIP;
  647. return (1);
  648. }
  649. /*
  650. * Internal version of TIFFFlushData that can be
  651. * called by ``encodestrip routines'' w/o concern
  652. * for infinite recursion.
  653. */
  654. int
  655. TIFFFlushData1(TIFF* tif)
  656. {
  657. if (tif->tif_rawcc > 0 && tif->tif_flags & TIFF_BUF4WRITE ) {
  658. if (!isFillOrder(tif, tif->tif_dir.td_fillorder) &&
  659. (tif->tif_flags & TIFF_NOBITREV) == 0)
  660. TIFFReverseBits((uint8*)tif->tif_rawdata,
  661. tif->tif_rawcc);
  662. if (!TIFFAppendToStrip(tif,
  663. isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip,
  664. tif->tif_rawdata, tif->tif_rawcc))
  665. return (0);
  666. tif->tif_rawcc = 0;
  667. tif->tif_rawcp = tif->tif_rawdata;
  668. }
  669. return (1);
  670. }
  671. /*
  672. * Set the current write offset. This should only be
  673. * used to set the offset to a known previous location
  674. * (very carefully), or to 0 so that the next write gets
  675. * appended to the end of the file.
  676. */
  677. void
  678. TIFFSetWriteOffset(TIFF* tif, toff_t off)
  679. {
  680. tif->tif_curoff = off;
  681. }
  682. /* vim: set ts=8 sts=8 sw=8 noet: */
  683. /*
  684. * Local Variables:
  685. * mode: c
  686. * c-basic-offset: 8
  687. * fill-column: 78
  688. * End:
  689. */