tif_write.c 25 KB

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