tif_write.c 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965
  1. /*
  2. * Copyright (c) 1988-1997 Sam Leffler
  3. * Copyright (c) 1991-1997 Silicon Graphics, Inc.
  4. *
  5. * Permission to use, copy, modify, distribute, and sell this software and
  6. * its documentation for any purpose is hereby granted without fee, provided
  7. * that (i) the above copyright notices and this permission notice appear in
  8. * all copies of the software and related documentation, and (ii) the names of
  9. * Sam Leffler and Silicon Graphics may not be used in any advertising or
  10. * publicity relating to the software without the specific, prior written
  11. * permission of Sam Leffler and Silicon Graphics.
  12. *
  13. * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
  14. * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
  15. * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
  16. *
  17. * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  18. * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  19. * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  20. * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
  21. * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
  22. * OF THIS SOFTWARE.
  23. */
  24. /*
  25. * TIFF Library.
  26. *
  27. * Scanline-oriented Write Support
  28. */
  29. #include "tiffiop.h"
  30. #include <stdio.h>
  31. #define STRIPINCR 20 /* expansion factor on strip array */
  32. #define WRITECHECKSTRIPS(tif, module) \
  33. (((tif)->tif_flags & TIFF_BEENWRITING) || TIFFWriteCheck((tif), 0, module))
  34. #define WRITECHECKTILES(tif, module) \
  35. (((tif)->tif_flags & TIFF_BEENWRITING) || TIFFWriteCheck((tif), 1, module))
  36. #define BUFFERCHECK(tif) \
  37. ((((tif)->tif_flags & TIFF_BUFFERSETUP) && tif->tif_rawdata) || \
  38. TIFFWriteBufferSetup((tif), NULL, (tmsize_t)-1))
  39. static int TIFFGrowStrips(TIFF *tif, uint32_t delta, const char *module);
  40. static int TIFFAppendToStrip(TIFF *tif, uint32_t strip, uint8_t *data,
  41. tmsize_t cc);
  42. int TIFFWriteScanline(TIFF *tif, void *buf, uint32_t row, uint16_t sample)
  43. {
  44. static const char module[] = "TIFFWriteScanline";
  45. register TIFFDirectory *td;
  46. int status, imagegrew = 0;
  47. uint32_t strip;
  48. if (!WRITECHECKSTRIPS(tif, module))
  49. return (-1);
  50. /*
  51. * Handle delayed allocation of data buffer. This
  52. * permits it to be sized more intelligently (using
  53. * directory information).
  54. */
  55. if (!BUFFERCHECK(tif))
  56. return (-1);
  57. tif->tif_flags |= TIFF_BUF4WRITE; /* not strictly sure this is right*/
  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)
  64. { /* extend image */
  65. if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
  66. {
  67. TIFFErrorExtR(
  68. tif, module,
  69. "Can not change \"ImageLength\" when using separate planes");
  70. return (-1);
  71. }
  72. td->td_imagelength = row + 1;
  73. imagegrew = 1;
  74. }
  75. /*
  76. * Calculate strip and check for crossings.
  77. */
  78. if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
  79. {
  80. if (sample >= td->td_samplesperpixel)
  81. {
  82. TIFFErrorExtR(tif, module, "%lu: Sample out of range, max %lu",
  83. (unsigned long)sample,
  84. (unsigned long)td->td_samplesperpixel);
  85. return (-1);
  86. }
  87. strip = sample * td->td_stripsperimage + row / td->td_rowsperstrip;
  88. }
  89. else
  90. strip = row / td->td_rowsperstrip;
  91. /*
  92. * Check strip array to make sure there's space. We don't support
  93. * dynamically growing files that have data organized in separate
  94. * bitplanes because it's too painful. In that case we require that
  95. * the imagelength be set properly before the first write (so that the
  96. * strips array will be fully allocated above).
  97. */
  98. if (strip >= td->td_nstrips && !TIFFGrowStrips(tif, 1, module))
  99. return (-1);
  100. if (strip != tif->tif_curstrip)
  101. {
  102. /*
  103. * Changing strips -- flush any data present.
  104. */
  105. if (!TIFFFlushData(tif))
  106. return (-1);
  107. tif->tif_curstrip = strip;
  108. /*
  109. * Watch out for a growing image. The value of strips/image
  110. * will initially be 1 (since it can't be deduced until the
  111. * imagelength is known).
  112. */
  113. if (strip >= td->td_stripsperimage && imagegrew)
  114. td->td_stripsperimage =
  115. TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip);
  116. if (td->td_stripsperimage == 0)
  117. {
  118. TIFFErrorExtR(tif, module, "Zero strips per image");
  119. return (-1);
  120. }
  121. tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
  122. if ((tif->tif_flags & TIFF_CODERSETUP) == 0)
  123. {
  124. if (!(*tif->tif_setupencode)(tif))
  125. return (-1);
  126. tif->tif_flags |= TIFF_CODERSETUP;
  127. }
  128. tif->tif_rawcc = 0;
  129. tif->tif_rawcp = tif->tif_rawdata;
  130. /* this informs TIFFAppendToStrip() we have changed strip */
  131. tif->tif_curoff = 0;
  132. if (!(*tif->tif_preencode)(tif, sample))
  133. return (-1);
  134. tif->tif_flags |= TIFF_POSTENCODE;
  135. }
  136. /*
  137. * Ensure the write is either sequential or at the
  138. * beginning of a strip (or that we can randomly
  139. * access the data -- i.e. no encoding).
  140. */
  141. if (row != tif->tif_row)
  142. {
  143. if (row < tif->tif_row)
  144. {
  145. /*
  146. * Moving backwards within the same strip:
  147. * backup to the start and then decode
  148. * forward (below).
  149. */
  150. tif->tif_row =
  151. (strip % td->td_stripsperimage) * td->td_rowsperstrip;
  152. tif->tif_rawcp = tif->tif_rawdata;
  153. }
  154. /*
  155. * Seek forward to the desired row.
  156. */
  157. if (!(*tif->tif_seek)(tif, row - tif->tif_row))
  158. return (-1);
  159. tif->tif_row = row;
  160. }
  161. /* swab if needed - note that source buffer will be altered */
  162. tif->tif_postdecode(tif, (uint8_t *)buf, tif->tif_scanlinesize);
  163. status = (*tif->tif_encoderow)(tif, (uint8_t *)buf, tif->tif_scanlinesize,
  164. sample);
  165. /* we are now poised at the beginning of the next row */
  166. tif->tif_row = row + 1;
  167. return (status);
  168. }
  169. /* Make sure that at the first attempt of rewriting a tile/strip, we will have
  170. */
  171. /* more bytes available in the output buffer than the previous byte count, */
  172. /* so that TIFFAppendToStrip() will detect the overflow when it is called the
  173. * first */
  174. /* time if the new compressed tile is bigger than the older one. (GDAL #4771) */
  175. static int _TIFFReserveLargeEnoughWriteBuffer(TIFF *tif, uint32_t strip_or_tile)
  176. {
  177. TIFFDirectory *td = &tif->tif_dir;
  178. if (td->td_stripbytecount_p[strip_or_tile] > 0)
  179. {
  180. /* The +1 is to ensure at least one extra bytes */
  181. /* The +4 is because the LZW encoder flushes 4 bytes before the limit */
  182. uint64_t safe_buffer_size =
  183. (uint64_t)(td->td_stripbytecount_p[strip_or_tile] + 1 + 4);
  184. if (tif->tif_rawdatasize <= (tmsize_t)safe_buffer_size)
  185. {
  186. if (!(TIFFWriteBufferSetup(
  187. tif, NULL,
  188. (tmsize_t)TIFFroundup_64(safe_buffer_size, 1024))))
  189. return 0;
  190. }
  191. }
  192. return 1;
  193. }
  194. /*
  195. * Encode the supplied data and write it to the
  196. * specified strip.
  197. *
  198. * NB: Image length must be setup before writing.
  199. */
  200. tmsize_t TIFFWriteEncodedStrip(TIFF *tif, uint32_t strip, void *data,
  201. tmsize_t cc)
  202. {
  203. static const char module[] = "TIFFWriteEncodedStrip";
  204. TIFFDirectory *td = &tif->tif_dir;
  205. uint16_t sample;
  206. if (!WRITECHECKSTRIPS(tif, module))
  207. return ((tmsize_t)-1);
  208. /*
  209. * Check strip array to make sure there's space.
  210. * We don't support dynamically growing files that
  211. * have data organized in separate bitplanes because
  212. * it's too painful. In that case we require that
  213. * the imagelength be set properly before the first
  214. * write (so that the strips array will be fully
  215. * allocated above).
  216. */
  217. if (strip >= td->td_nstrips)
  218. {
  219. if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
  220. {
  221. TIFFErrorExtR(
  222. tif, module,
  223. "Can not grow image by strips when using separate planes");
  224. return ((tmsize_t)-1);
  225. }
  226. if (!TIFFGrowStrips(tif, 1, module))
  227. return ((tmsize_t)-1);
  228. td->td_stripsperimage =
  229. TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip);
  230. }
  231. /*
  232. * Handle delayed allocation of data buffer. This
  233. * permits it to be sized according to the directory
  234. * info.
  235. */
  236. if (!BUFFERCHECK(tif))
  237. return ((tmsize_t)-1);
  238. tif->tif_flags |= TIFF_BUF4WRITE;
  239. tif->tif_curstrip = strip;
  240. /* this informs TIFFAppendToStrip() we have changed or reset strip */
  241. tif->tif_curoff = 0;
  242. if (!_TIFFReserveLargeEnoughWriteBuffer(tif, strip))
  243. {
  244. return ((tmsize_t)(-1));
  245. }
  246. tif->tif_rawcc = 0;
  247. tif->tif_rawcp = tif->tif_rawdata;
  248. if (td->td_stripsperimage == 0)
  249. {
  250. TIFFErrorExtR(tif, module, "Zero strips per image");
  251. return ((tmsize_t)-1);
  252. }
  253. tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
  254. if ((tif->tif_flags & TIFF_CODERSETUP) == 0)
  255. {
  256. if (!(*tif->tif_setupencode)(tif))
  257. return ((tmsize_t)-1);
  258. tif->tif_flags |= TIFF_CODERSETUP;
  259. }
  260. tif->tif_flags &= ~TIFF_POSTENCODE;
  261. /* shortcut to avoid an extra memcpy() */
  262. if (td->td_compression == COMPRESSION_NONE)
  263. {
  264. /* swab if needed - note that source buffer will be altered */
  265. tif->tif_postdecode(tif, (uint8_t *)data, cc);
  266. if (!isFillOrder(tif, td->td_fillorder) &&
  267. (tif->tif_flags & TIFF_NOBITREV) == 0)
  268. TIFFReverseBits((uint8_t *)data, cc);
  269. if (cc > 0 && !TIFFAppendToStrip(tif, strip, (uint8_t *)data, cc))
  270. return ((tmsize_t)-1);
  271. return (cc);
  272. }
  273. sample = (uint16_t)(strip / td->td_stripsperimage);
  274. if (!(*tif->tif_preencode)(tif, sample))
  275. return ((tmsize_t)-1);
  276. /* swab if needed - note that source buffer will be altered */
  277. tif->tif_postdecode(tif, (uint8_t *)data, cc);
  278. if (!(*tif->tif_encodestrip)(tif, (uint8_t *)data, cc, sample))
  279. return ((tmsize_t)-1);
  280. if (!(*tif->tif_postencode)(tif))
  281. return ((tmsize_t)-1);
  282. if (!isFillOrder(tif, td->td_fillorder) &&
  283. (tif->tif_flags & TIFF_NOBITREV) == 0)
  284. TIFFReverseBits(tif->tif_rawdata, tif->tif_rawcc);
  285. if (tif->tif_rawcc > 0 &&
  286. !TIFFAppendToStrip(tif, strip, tif->tif_rawdata, tif->tif_rawcc))
  287. return ((tmsize_t)-1);
  288. tif->tif_rawcc = 0;
  289. tif->tif_rawcp = tif->tif_rawdata;
  290. return (cc);
  291. }
  292. /*
  293. * Write the supplied data to the specified strip.
  294. *
  295. * NB: Image length must be setup before writing.
  296. */
  297. tmsize_t TIFFWriteRawStrip(TIFF *tif, uint32_t strip, void *data, tmsize_t cc)
  298. {
  299. static const char module[] = "TIFFWriteRawStrip";
  300. TIFFDirectory *td = &tif->tif_dir;
  301. if (!WRITECHECKSTRIPS(tif, module))
  302. return ((tmsize_t)-1);
  303. /*
  304. * Check strip array to make sure there's space.
  305. * We don't support dynamically growing files that
  306. * have data organized in separate bitplanes because
  307. * it's too painful. In that case we require that
  308. * the imagelength be set properly before the first
  309. * write (so that the strips array will be fully
  310. * allocated above).
  311. */
  312. if (strip >= td->td_nstrips)
  313. {
  314. if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
  315. {
  316. TIFFErrorExtR(
  317. tif, module,
  318. "Can not grow image by strips when using separate planes");
  319. return ((tmsize_t)-1);
  320. }
  321. /*
  322. * Watch out for a growing image. The value of
  323. * strips/image will initially be 1 (since it
  324. * can't be deduced until the imagelength is known).
  325. */
  326. if (strip >= td->td_stripsperimage)
  327. td->td_stripsperimage =
  328. TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip);
  329. if (!TIFFGrowStrips(tif, 1, module))
  330. return ((tmsize_t)-1);
  331. }
  332. if (tif->tif_curstrip != strip)
  333. {
  334. tif->tif_curstrip = strip;
  335. /* this informs TIFFAppendToStrip() we have changed or reset strip */
  336. tif->tif_curoff = 0;
  337. }
  338. if (td->td_stripsperimage == 0)
  339. {
  340. TIFFErrorExtR(tif, module, "Zero strips per image");
  341. return ((tmsize_t)-1);
  342. }
  343. tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
  344. return (TIFFAppendToStrip(tif, strip, (uint8_t *)data, cc) ? cc
  345. : (tmsize_t)-1);
  346. }
  347. /*
  348. * Write and compress a tile of data. The
  349. * tile is selected by the (x,y,z,s) coordinates.
  350. */
  351. tmsize_t TIFFWriteTile(TIFF *tif, void *buf, uint32_t x, uint32_t y, uint32_t z,
  352. uint16_t s)
  353. {
  354. if (!TIFFCheckTile(tif, x, y, z, s))
  355. return ((tmsize_t)(-1));
  356. /*
  357. * NB: A tile size of -1 is used instead of tif_tilesize knowing
  358. * that TIFFWriteEncodedTile will clamp this to the tile size.
  359. * This is done because the tile size may not be defined until
  360. * after the output buffer is setup in TIFFWriteBufferSetup.
  361. */
  362. return (TIFFWriteEncodedTile(tif, TIFFComputeTile(tif, x, y, z, s), buf,
  363. (tmsize_t)(-1)));
  364. }
  365. /*
  366. * Encode the supplied data and write it to the
  367. * specified tile. There must be space for the
  368. * data. The function clamps individual writes
  369. * to a tile to the tile size, but does not (and
  370. * can not) check that multiple writes to the same
  371. * tile do not write more than tile size data.
  372. *
  373. * NB: Image length must be setup before writing; this
  374. * interface does not support automatically growing
  375. * the image on each write (as TIFFWriteScanline does).
  376. */
  377. tmsize_t TIFFWriteEncodedTile(TIFF *tif, uint32_t tile, void *data, tmsize_t cc)
  378. {
  379. static const char module[] = "TIFFWriteEncodedTile";
  380. TIFFDirectory *td;
  381. uint16_t sample;
  382. uint32_t howmany32;
  383. if (!WRITECHECKTILES(tif, module))
  384. return ((tmsize_t)(-1));
  385. td = &tif->tif_dir;
  386. if (tile >= td->td_nstrips)
  387. {
  388. TIFFErrorExtR(tif, module, "Tile %lu out of range, max %lu",
  389. (unsigned long)tile, (unsigned long)td->td_nstrips);
  390. return ((tmsize_t)(-1));
  391. }
  392. /*
  393. * Handle delayed allocation of data buffer. This
  394. * permits it to be sized more intelligently (using
  395. * directory information).
  396. */
  397. if (!BUFFERCHECK(tif))
  398. return ((tmsize_t)(-1));
  399. tif->tif_flags |= TIFF_BUF4WRITE;
  400. tif->tif_curtile = tile;
  401. /* this informs TIFFAppendToStrip() we have changed or reset tile */
  402. tif->tif_curoff = 0;
  403. if (!_TIFFReserveLargeEnoughWriteBuffer(tif, tile))
  404. {
  405. return ((tmsize_t)(-1));
  406. }
  407. tif->tif_rawcc = 0;
  408. tif->tif_rawcp = tif->tif_rawdata;
  409. /*
  410. * Compute tiles per row & per column to compute
  411. * current row and column
  412. */
  413. howmany32 = TIFFhowmany_32(td->td_imagelength, td->td_tilelength);
  414. if (howmany32 == 0)
  415. {
  416. TIFFErrorExtR(tif, module, "Zero tiles");
  417. return ((tmsize_t)(-1));
  418. }
  419. tif->tif_row = (tile % howmany32) * td->td_tilelength;
  420. howmany32 = TIFFhowmany_32(td->td_imagewidth, td->td_tilewidth);
  421. if (howmany32 == 0)
  422. {
  423. TIFFErrorExtR(tif, module, "Zero tiles");
  424. return ((tmsize_t)(-1));
  425. }
  426. tif->tif_col = (tile % howmany32) * td->td_tilewidth;
  427. if ((tif->tif_flags & TIFF_CODERSETUP) == 0)
  428. {
  429. if (!(*tif->tif_setupencode)(tif))
  430. return ((tmsize_t)(-1));
  431. tif->tif_flags |= TIFF_CODERSETUP;
  432. }
  433. tif->tif_flags &= ~TIFF_POSTENCODE;
  434. /*
  435. * Clamp write amount to the tile size. This is mostly
  436. * done so that callers can pass in some large number
  437. * (e.g. -1) and have the tile size used instead.
  438. */
  439. if (cc < 1 || cc > tif->tif_tilesize)
  440. cc = tif->tif_tilesize;
  441. /* shortcut to avoid an extra memcpy() */
  442. if (td->td_compression == COMPRESSION_NONE)
  443. {
  444. /* swab if needed - note that source buffer will be altered */
  445. tif->tif_postdecode(tif, (uint8_t *)data, cc);
  446. if (!isFillOrder(tif, td->td_fillorder) &&
  447. (tif->tif_flags & TIFF_NOBITREV) == 0)
  448. TIFFReverseBits((uint8_t *)data, cc);
  449. if (cc > 0 && !TIFFAppendToStrip(tif, tile, (uint8_t *)data, cc))
  450. return ((tmsize_t)-1);
  451. return (cc);
  452. }
  453. sample = (uint16_t)(tile / td->td_stripsperimage);
  454. if (!(*tif->tif_preencode)(tif, sample))
  455. return ((tmsize_t)(-1));
  456. /* swab if needed - note that source buffer will be altered */
  457. tif->tif_postdecode(tif, (uint8_t *)data, cc);
  458. if (!(*tif->tif_encodetile)(tif, (uint8_t *)data, cc, sample))
  459. return ((tmsize_t)-1);
  460. if (!(*tif->tif_postencode)(tif))
  461. return ((tmsize_t)(-1));
  462. if (!isFillOrder(tif, td->td_fillorder) &&
  463. (tif->tif_flags & TIFF_NOBITREV) == 0)
  464. TIFFReverseBits((uint8_t *)tif->tif_rawdata, tif->tif_rawcc);
  465. if (tif->tif_rawcc > 0 &&
  466. !TIFFAppendToStrip(tif, tile, tif->tif_rawdata, tif->tif_rawcc))
  467. return ((tmsize_t)(-1));
  468. tif->tif_rawcc = 0;
  469. tif->tif_rawcp = tif->tif_rawdata;
  470. return (cc);
  471. }
  472. /*
  473. * Write the supplied data to the specified strip.
  474. * There must be space for the data; we don't check
  475. * if strips overlap!
  476. *
  477. * NB: Image length must be setup before writing; this
  478. * interface does not support automatically growing
  479. * the image on each write (as TIFFWriteScanline does).
  480. */
  481. tmsize_t TIFFWriteRawTile(TIFF *tif, uint32_t tile, void *data, tmsize_t cc)
  482. {
  483. static const char module[] = "TIFFWriteRawTile";
  484. if (!WRITECHECKTILES(tif, module))
  485. return ((tmsize_t)(-1));
  486. if (tile >= tif->tif_dir.td_nstrips)
  487. {
  488. TIFFErrorExtR(tif, module, "Tile %lu out of range, max %lu",
  489. (unsigned long)tile,
  490. (unsigned long)tif->tif_dir.td_nstrips);
  491. return ((tmsize_t)(-1));
  492. }
  493. return (TIFFAppendToStrip(tif, tile, (uint8_t *)data, cc) ? cc
  494. : (tmsize_t)(-1));
  495. }
  496. #define isUnspecified(tif, f) \
  497. (TIFFFieldSet(tif, f) && (tif)->tif_dir.td_imagelength == 0)
  498. int TIFFSetupStrips(TIFF *tif)
  499. {
  500. TIFFDirectory *td = &tif->tif_dir;
  501. if (isTiled(tif))
  502. td->td_stripsperimage = isUnspecified(tif, FIELD_TILEDIMENSIONS)
  503. ? td->td_samplesperpixel
  504. : TIFFNumberOfTiles(tif);
  505. else
  506. td->td_stripsperimage = isUnspecified(tif, FIELD_ROWSPERSTRIP)
  507. ? td->td_samplesperpixel
  508. : TIFFNumberOfStrips(tif);
  509. td->td_nstrips = td->td_stripsperimage;
  510. /* TIFFWriteDirectoryTagData has a limitation to 0x80000000U bytes */
  511. if (td->td_nstrips >=
  512. 0x80000000U / ((tif->tif_flags & TIFF_BIGTIFF) ? 0x8U : 0x4U))
  513. {
  514. TIFFErrorExtR(tif, "TIFFSetupStrips",
  515. "Too large Strip/Tile Offsets/ByteCounts arrays");
  516. return 0;
  517. }
  518. if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
  519. td->td_stripsperimage /= td->td_samplesperpixel;
  520. if (td->td_stripoffset_p != NULL)
  521. _TIFFfreeExt(tif, td->td_stripoffset_p);
  522. td->td_stripoffset_p = (uint64_t *)_TIFFCheckMalloc(
  523. tif, td->td_nstrips, sizeof(uint64_t), "for \"StripOffsets\" array");
  524. if (td->td_stripbytecount_p != NULL)
  525. _TIFFfreeExt(tif, td->td_stripbytecount_p);
  526. td->td_stripbytecount_p = (uint64_t *)_TIFFCheckMalloc(
  527. tif, td->td_nstrips, sizeof(uint64_t), "for \"StripByteCounts\" array");
  528. if (td->td_stripoffset_p == NULL || td->td_stripbytecount_p == NULL)
  529. return (0);
  530. /*
  531. * Place data at the end-of-file
  532. * (by setting offsets to zero).
  533. */
  534. _TIFFmemset(td->td_stripoffset_p, 0, td->td_nstrips * sizeof(uint64_t));
  535. _TIFFmemset(td->td_stripbytecount_p, 0, td->td_nstrips * sizeof(uint64_t));
  536. TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS);
  537. TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS);
  538. return (1);
  539. }
  540. #undef isUnspecified
  541. /*
  542. * Verify file is writable and that the directory
  543. * information is setup properly. In doing the latter
  544. * we also "freeze" the state of the directory so
  545. * that important information is not changed.
  546. */
  547. int TIFFWriteCheck(TIFF *tif, int tiles, const char *module)
  548. {
  549. if (tif->tif_mode == O_RDONLY)
  550. {
  551. TIFFErrorExtR(tif, module, "File not open for writing");
  552. return (0);
  553. }
  554. if (tiles ^ isTiled(tif))
  555. {
  556. TIFFErrorExtR(tif, module,
  557. tiles ? "Can not write tiles to a striped image"
  558. : "Can not write scanlines to a tiled image");
  559. return (0);
  560. }
  561. _TIFFFillStriles(tif);
  562. /*
  563. * On the first write verify all the required information
  564. * has been setup and initialize any data structures that
  565. * had to wait until directory information was set.
  566. * Note that a lot of our work is assumed to remain valid
  567. * because we disallow any of the important parameters
  568. * from changing after we start writing (i.e. once
  569. * TIFF_BEENWRITING is set, TIFFSetField will only allow
  570. * the image's length to be changed).
  571. */
  572. if (!TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS))
  573. {
  574. TIFFErrorExtR(tif, module,
  575. "Must set \"ImageWidth\" before writing data");
  576. return (0);
  577. }
  578. if (tif->tif_dir.td_stripoffset_p == NULL && !TIFFSetupStrips(tif))
  579. {
  580. tif->tif_dir.td_nstrips = 0;
  581. TIFFErrorExtR(tif, module, "No space for %s arrays",
  582. isTiled(tif) ? "tile" : "strip");
  583. return (0);
  584. }
  585. if (isTiled(tif))
  586. {
  587. tif->tif_tilesize = TIFFTileSize(tif);
  588. if (tif->tif_tilesize == 0)
  589. return (0);
  590. }
  591. else
  592. tif->tif_tilesize = (tmsize_t)(-1);
  593. tif->tif_scanlinesize = TIFFScanlineSize(tif);
  594. if (tif->tif_scanlinesize == 0)
  595. return (0);
  596. tif->tif_flags |= TIFF_BEENWRITING;
  597. if (tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 &&
  598. tif->tif_dir.td_stripoffset_entry.tdir_count == 0 &&
  599. tif->tif_dir.td_stripoffset_entry.tdir_type == 0 &&
  600. tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0 &&
  601. tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 &&
  602. tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 &&
  603. tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 &&
  604. tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0 &&
  605. !(tif->tif_flags & TIFF_DIRTYDIRECT))
  606. {
  607. TIFFForceStrileArrayWriting(tif);
  608. }
  609. return (1);
  610. }
  611. /*
  612. * Setup the raw data buffer used for encoding.
  613. */
  614. int TIFFWriteBufferSetup(TIFF *tif, void *bp, tmsize_t size)
  615. {
  616. static const char module[] = "TIFFWriteBufferSetup";
  617. if (tif->tif_rawdata)
  618. {
  619. if (tif->tif_flags & TIFF_MYBUFFER)
  620. {
  621. _TIFFfreeExt(tif, tif->tif_rawdata);
  622. tif->tif_flags &= ~TIFF_MYBUFFER;
  623. }
  624. tif->tif_rawdata = NULL;
  625. }
  626. if (size == (tmsize_t)(-1))
  627. {
  628. size = (isTiled(tif) ? tif->tif_tilesize : TIFFStripSize(tif));
  629. /* Adds 10% margin for cases where compression would expand a bit */
  630. if (size < TIFF_TMSIZE_T_MAX - size / 10)
  631. size += size / 10;
  632. /*
  633. * Make raw data buffer at least 8K
  634. */
  635. if (size < 8 * 1024)
  636. size = 8 * 1024;
  637. bp = NULL; /* NB: force malloc */
  638. }
  639. if (bp == NULL)
  640. {
  641. bp = _TIFFmallocExt(tif, size);
  642. if (bp == NULL)
  643. {
  644. TIFFErrorExtR(tif, module, "No space for output buffer");
  645. return (0);
  646. }
  647. tif->tif_flags |= TIFF_MYBUFFER;
  648. }
  649. else
  650. tif->tif_flags &= ~TIFF_MYBUFFER;
  651. tif->tif_rawdata = (uint8_t *)bp;
  652. tif->tif_rawdatasize = size;
  653. tif->tif_rawcc = 0;
  654. tif->tif_rawcp = tif->tif_rawdata;
  655. tif->tif_flags |= TIFF_BUFFERSETUP;
  656. return (1);
  657. }
  658. /*
  659. * Grow the strip data structures by delta strips.
  660. */
  661. static int TIFFGrowStrips(TIFF *tif, uint32_t delta, const char *module)
  662. {
  663. TIFFDirectory *td = &tif->tif_dir;
  664. uint64_t *new_stripoffset;
  665. uint64_t *new_stripbytecount;
  666. assert(td->td_planarconfig == PLANARCONFIG_CONTIG);
  667. new_stripoffset = (uint64_t *)_TIFFreallocExt(
  668. tif, td->td_stripoffset_p, (td->td_nstrips + delta) * sizeof(uint64_t));
  669. new_stripbytecount = (uint64_t *)_TIFFreallocExt(
  670. tif, td->td_stripbytecount_p,
  671. (td->td_nstrips + delta) * sizeof(uint64_t));
  672. if (new_stripoffset == NULL || new_stripbytecount == NULL)
  673. {
  674. if (new_stripoffset)
  675. _TIFFfreeExt(tif, new_stripoffset);
  676. if (new_stripbytecount)
  677. _TIFFfreeExt(tif, new_stripbytecount);
  678. td->td_nstrips = 0;
  679. TIFFErrorExtR(tif, module, "No space to expand strip arrays");
  680. return (0);
  681. }
  682. td->td_stripoffset_p = new_stripoffset;
  683. td->td_stripbytecount_p = new_stripbytecount;
  684. _TIFFmemset(td->td_stripoffset_p + td->td_nstrips, 0,
  685. delta * sizeof(uint64_t));
  686. _TIFFmemset(td->td_stripbytecount_p + td->td_nstrips, 0,
  687. delta * sizeof(uint64_t));
  688. td->td_nstrips += delta;
  689. tif->tif_flags |= TIFF_DIRTYDIRECT;
  690. return (1);
  691. }
  692. /*
  693. * Append the data to the specified strip.
  694. */
  695. static int TIFFAppendToStrip(TIFF *tif, uint32_t strip, uint8_t *data,
  696. tmsize_t cc)
  697. {
  698. static const char module[] = "TIFFAppendToStrip";
  699. TIFFDirectory *td = &tif->tif_dir;
  700. uint64_t m;
  701. int64_t old_byte_count = -1;
  702. if (tif->tif_curoff == 0)
  703. tif->tif_lastvalidoff = 0;
  704. if (td->td_stripoffset_p[strip] == 0 || tif->tif_curoff == 0)
  705. {
  706. assert(td->td_nstrips > 0);
  707. if (td->td_stripbytecount_p[strip] != 0 &&
  708. td->td_stripoffset_p[strip] != 0 &&
  709. td->td_stripbytecount_p[strip] >= (uint64_t)cc)
  710. {
  711. /*
  712. * There is already tile data on disk, and the new tile
  713. * data we have will fit in the same space. The only
  714. * aspect of this that is risky is that there could be
  715. * more data to append to this strip before we are done
  716. * depending on how we are getting called.
  717. */
  718. if (!SeekOK(tif, td->td_stripoffset_p[strip]))
  719. {
  720. TIFFErrorExtR(tif, module, "Seek error at scanline %lu",
  721. (unsigned long)tif->tif_row);
  722. return (0);
  723. }
  724. tif->tif_lastvalidoff =
  725. td->td_stripoffset_p[strip] + td->td_stripbytecount_p[strip];
  726. }
  727. else
  728. {
  729. /*
  730. * Seek to end of file, and set that as our location to
  731. * write this strip.
  732. */
  733. td->td_stripoffset_p[strip] = TIFFSeekFile(tif, 0, SEEK_END);
  734. tif->tif_flags |= TIFF_DIRTYSTRIP;
  735. }
  736. tif->tif_curoff = td->td_stripoffset_p[strip];
  737. /*
  738. * We are starting a fresh strip/tile, so set the size to zero.
  739. */
  740. old_byte_count = td->td_stripbytecount_p[strip];
  741. td->td_stripbytecount_p[strip] = 0;
  742. }
  743. m = tif->tif_curoff + cc;
  744. if (!(tif->tif_flags & TIFF_BIGTIFF))
  745. m = (uint32_t)m;
  746. if ((m < tif->tif_curoff) || (m < (uint64_t)cc))
  747. {
  748. TIFFErrorExtR(tif, module, "Maximum TIFF file size exceeded");
  749. return (0);
  750. }
  751. if (tif->tif_lastvalidoff != 0 && m > tif->tif_lastvalidoff &&
  752. td->td_stripbytecount_p[strip] > 0)
  753. {
  754. /* Ouch: we have detected that we are rewriting in place a strip/tile */
  755. /* with several calls to TIFFAppendToStrip(). The first call was with */
  756. /* a size smaller than the previous size of the strip/tile, so we */
  757. /* opted to rewrite in place, but a following call causes us to go */
  758. /* outsize of the strip/tile area, so we have to finally go for a */
  759. /* append-at-end-of-file strategy, and start by moving what we already
  760. */
  761. /* wrote. */
  762. tmsize_t tempSize;
  763. void *temp;
  764. uint64_t offsetRead;
  765. uint64_t offsetWrite;
  766. uint64_t toCopy = td->td_stripbytecount_p[strip];
  767. if (toCopy < 1024 * 1024)
  768. tempSize = (tmsize_t)toCopy;
  769. else
  770. tempSize = 1024 * 1024;
  771. offsetRead = td->td_stripoffset_p[strip];
  772. offsetWrite = TIFFSeekFile(tif, 0, SEEK_END);
  773. m = offsetWrite + toCopy + cc;
  774. if (!(tif->tif_flags & TIFF_BIGTIFF) && m != (uint32_t)m)
  775. {
  776. TIFFErrorExtR(tif, module, "Maximum TIFF file size exceeded");
  777. return (0);
  778. }
  779. temp = _TIFFmallocExt(tif, tempSize);
  780. if (temp == NULL)
  781. {
  782. TIFFErrorExtR(tif, module, "No space for output buffer");
  783. return (0);
  784. }
  785. tif->tif_flags |= TIFF_DIRTYSTRIP;
  786. td->td_stripoffset_p[strip] = offsetWrite;
  787. td->td_stripbytecount_p[strip] = 0;
  788. /* Move data written by previous calls to us at end of file */
  789. while (toCopy > 0)
  790. {
  791. if (!SeekOK(tif, offsetRead))
  792. {
  793. TIFFErrorExtR(tif, module, "Seek error");
  794. _TIFFfreeExt(tif, temp);
  795. return (0);
  796. }
  797. if (!ReadOK(tif, temp, tempSize))
  798. {
  799. TIFFErrorExtR(tif, module, "Cannot read");
  800. _TIFFfreeExt(tif, temp);
  801. return (0);
  802. }
  803. if (!SeekOK(tif, offsetWrite))
  804. {
  805. TIFFErrorExtR(tif, module, "Seek error");
  806. _TIFFfreeExt(tif, temp);
  807. return (0);
  808. }
  809. if (!WriteOK(tif, temp, tempSize))
  810. {
  811. TIFFErrorExtR(tif, module, "Cannot write");
  812. _TIFFfreeExt(tif, temp);
  813. return (0);
  814. }
  815. offsetRead += tempSize;
  816. offsetWrite += tempSize;
  817. td->td_stripbytecount_p[strip] += tempSize;
  818. toCopy -= tempSize;
  819. }
  820. _TIFFfreeExt(tif, temp);
  821. /* Append the data of this call */
  822. offsetWrite += cc;
  823. m = offsetWrite;
  824. }
  825. if (!WriteOK(tif, data, cc))
  826. {
  827. TIFFErrorExtR(tif, module, "Write error at scanline %lu",
  828. (unsigned long)tif->tif_row);
  829. return (0);
  830. }
  831. tif->tif_curoff = m;
  832. td->td_stripbytecount_p[strip] += cc;
  833. if ((int64_t)td->td_stripbytecount_p[strip] != old_byte_count)
  834. tif->tif_flags |= TIFF_DIRTYSTRIP;
  835. return (1);
  836. }
  837. /*
  838. * Internal version of TIFFFlushData that can be
  839. * called by ``encodestrip routines'' w/o concern
  840. * for infinite recursion.
  841. */
  842. int TIFFFlushData1(TIFF *tif)
  843. {
  844. if (tif->tif_rawcc > 0 && tif->tif_flags & TIFF_BUF4WRITE)
  845. {
  846. if (!isFillOrder(tif, tif->tif_dir.td_fillorder) &&
  847. (tif->tif_flags & TIFF_NOBITREV) == 0)
  848. TIFFReverseBits((uint8_t *)tif->tif_rawdata, tif->tif_rawcc);
  849. if (!TIFFAppendToStrip(
  850. tif, isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip,
  851. tif->tif_rawdata, tif->tif_rawcc))
  852. {
  853. /* We update those variables even in case of error since there's */
  854. /* code that doesn't really check the return code of this */
  855. /* function */
  856. tif->tif_rawcc = 0;
  857. tif->tif_rawcp = tif->tif_rawdata;
  858. return (0);
  859. }
  860. tif->tif_rawcc = 0;
  861. tif->tif_rawcp = tif->tif_rawdata;
  862. }
  863. return (1);
  864. }
  865. /*
  866. * Set the current write offset. This should only be
  867. * used to set the offset to a known previous location
  868. * (very carefully), or to 0 so that the next write gets
  869. * appended to the end of the file.
  870. */
  871. void TIFFSetWriteOffset(TIFF *tif, toff_t off)
  872. {
  873. tif->tif_curoff = off;
  874. tif->tif_lastvalidoff = 0;
  875. }