ReactOS  0.4.13-dev-259-g5ca9c9c
tif_write.c
Go to the documentation of this file.
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 /*
26  * TIFF Library.
27  *
28  * Scanline-oriented Write Support
29  */
30 
31 #include <precomp.h>
32 //#include <stdio.h>
33 
34 #define STRIPINCR 20 /* expansion factor on strip array */
35 
36 #define WRITECHECKSTRIPS(tif, module) \
37  (((tif)->tif_flags&TIFF_BEENWRITING) || TIFFWriteCheck((tif),0,module))
38 #define WRITECHECKTILES(tif, module) \
39  (((tif)->tif_flags&TIFF_BEENWRITING) || TIFFWriteCheck((tif),1,module))
40 #define BUFFERCHECK(tif) \
41  ((((tif)->tif_flags & TIFF_BUFFERSETUP) && tif->tif_rawdata) || \
42  TIFFWriteBufferSetup((tif), NULL, (tmsize_t) -1))
43 
44 static int TIFFGrowStrips(TIFF* tif, uint32 delta, const char* module);
45 static int TIFFAppendToStrip(TIFF* tif, uint32 strip, uint8* data, tmsize_t cc);
46 
47 int
48 TIFFWriteScanline(TIFF* tif, void* buf, uint32 row, uint16 sample)
49 {
50  static const char module[] = "TIFFWriteScanline";
51  register TIFFDirectory *td;
52  int status, imagegrew = 0;
53  uint32 strip;
54 
55  if (!WRITECHECKSTRIPS(tif, module))
56  return (-1);
57  /*
58  * Handle delayed allocation of data buffer. This
59  * permits it to be sized more intelligently (using
60  * directory information).
61  */
62  if (!BUFFERCHECK(tif))
63  return (-1);
64  tif->tif_flags |= TIFF_BUF4WRITE; /* not strictly sure this is right*/
65 
66  td = &tif->tif_dir;
67  /*
68  * Extend image length if needed
69  * (but only for PlanarConfig=1).
70  */
71  if (row >= td->td_imagelength) { /* extend image */
74  "Can not change \"ImageLength\" when using separate planes");
75  return (-1);
76  }
77  td->td_imagelength = row+1;
78  imagegrew = 1;
79  }
80  /*
81  * Calculate strip and check for crossings.
82  */
84  if (sample >= td->td_samplesperpixel) {
86  "%lu: Sample out of range, max %lu",
87  (unsigned long) sample, (unsigned long) td->td_samplesperpixel);
88  return (-1);
89  }
90  strip = sample*td->td_stripsperimage + row/td->td_rowsperstrip;
91  } else
92  strip = row / td->td_rowsperstrip;
93  /*
94  * Check strip array to make sure there's space. We don't support
95  * dynamically growing files that have data organized in separate
96  * bitplanes because it's too painful. In that case we require that
97  * the imagelength be set properly before the first write (so that the
98  * strips array will be fully allocated above).
99  */
100  if (strip >= td->td_nstrips && !TIFFGrowStrips(tif, 1, module))
101  return (-1);
102  if (strip != tif->tif_curstrip) {
103  /*
104  * Changing strips -- flush any data present.
105  */
106  if (!TIFFFlushData(tif))
107  return (-1);
108  tif->tif_curstrip = strip;
109  /*
110  * Watch out for a growing image. The value of strips/image
111  * will initially be 1 (since it can't be deduced until the
112  * imagelength is known).
113  */
114  if (strip >= td->td_stripsperimage && imagegrew)
115  td->td_stripsperimage =
117  if (td->td_stripsperimage == 0) {
118  TIFFErrorExt(tif->tif_clientdata, module, "Zero strips per image");
119  return (-1);
120  }
121  tif->tif_row =
122  (strip % td->td_stripsperimage) * td->td_rowsperstrip;
123  if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
124  if (!(*tif->tif_setupencode)(tif))
125  return (-1);
126  tif->tif_flags |= TIFF_CODERSETUP;
127  }
128 
129  tif->tif_rawcc = 0;
130  tif->tif_rawcp = tif->tif_rawdata;
131 
132  if( td->td_stripbytecount[strip] > 0 )
133  {
134  /* if we are writing over existing tiles, zero length */
135  td->td_stripbytecount[strip] = 0;
136 
137  /* this forces TIFFAppendToStrip() to do a seek */
138  tif->tif_curoff = 0;
139  }
140 
141  if (!(*tif->tif_preencode)(tif, sample))
142  return (-1);
143  tif->tif_flags |= TIFF_POSTENCODE;
144  }
145  /*
146  * Ensure the write is either sequential or at the
147  * beginning of a strip (or that we can randomly
148  * access the data -- i.e. no encoding).
149  */
150  if (row != tif->tif_row) {
151  if (row < tif->tif_row) {
152  /*
153  * Moving backwards within the same strip:
154  * backup to the start and then decode
155  * forward (below).
156  */
157  tif->tif_row = (strip % td->td_stripsperimage) *
158  td->td_rowsperstrip;
159  tif->tif_rawcp = tif->tif_rawdata;
160  }
161  /*
162  * Seek forward to the desired row.
163  */
164  if (!(*tif->tif_seek)(tif, row - tif->tif_row))
165  return (-1);
166  tif->tif_row = row;
167  }
168 
169  /* swab if needed - note that source buffer will be altered */
170  tif->tif_postdecode( tif, (uint8*) buf, tif->tif_scanlinesize );
171 
172  status = (*tif->tif_encoderow)(tif, (uint8*) buf,
173  tif->tif_scanlinesize, sample);
174 
175  /* we are now poised at the beginning of the next row */
176  tif->tif_row = row + 1;
177  return (status);
178 }
179 
180 /*
181  * Encode the supplied data and write it to the
182  * specified strip.
183  *
184  * NB: Image length must be setup before writing.
185  */
186 tmsize_t
188 {
189  static const char module[] = "TIFFWriteEncodedStrip";
190  TIFFDirectory *td = &tif->tif_dir;
191  uint16 sample;
192 
193  if (!WRITECHECKSTRIPS(tif, module))
194  return ((tmsize_t) -1);
195  /*
196  * Check strip array to make sure there's space.
197  * We don't support dynamically growing files that
198  * have data organized in separate bitplanes because
199  * it's too painful. In that case we require that
200  * the imagelength be set properly before the first
201  * write (so that the strips array will be fully
202  * allocated above).
203  */
204  if (strip >= td->td_nstrips) {
207  "Can not grow image by strips when using separate planes");
208  return ((tmsize_t) -1);
209  }
210  if (!TIFFGrowStrips(tif, 1, module))
211  return ((tmsize_t) -1);
212  td->td_stripsperimage =
214  }
215  /*
216  * Handle delayed allocation of data buffer. This
217  * permits it to be sized according to the directory
218  * info.
219  */
220  if (!BUFFERCHECK(tif))
221  return ((tmsize_t) -1);
222 
223  tif->tif_flags |= TIFF_BUF4WRITE;
224  tif->tif_curstrip = strip;
225 
226  if (td->td_stripsperimage == 0) {
227  TIFFErrorExt(tif->tif_clientdata, module, "Zero strips per image");
228  return ((tmsize_t) -1);
229  }
230 
231  tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
232  if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
233  if (!(*tif->tif_setupencode)(tif))
234  return ((tmsize_t) -1);
235  tif->tif_flags |= TIFF_CODERSETUP;
236  }
237 
238  if( td->td_stripbytecount[strip] > 0 )
239  {
240  /* Make sure that at the first attempt of rewriting the tile, we will have */
241  /* more bytes available in the output buffer than the previous byte count, */
242  /* so that TIFFAppendToStrip() will detect the overflow when it is called the first */
243  /* time if the new compressed tile is bigger than the older one. (GDAL #4771) */
244  if( tif->tif_rawdatasize <= (tmsize_t)td->td_stripbytecount[strip] )
245  {
246  if( !(TIFFWriteBufferSetup(tif, NULL,
247  (tmsize_t)TIFFroundup_64((uint64)(td->td_stripbytecount[strip] + 1), 1024))) )
248  return ((tmsize_t)(-1));
249  }
250 
251  /* Force TIFFAppendToStrip() to consider placing data at end
252  of file. */
253  tif->tif_curoff = 0;
254  }
255 
256  tif->tif_rawcc = 0;
257  tif->tif_rawcp = tif->tif_rawdata;
258 
259  tif->tif_flags &= ~TIFF_POSTENCODE;
260 
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*) data, cc );
266 
267  if (!isFillOrder(tif, td->td_fillorder) &&
268  (tif->tif_flags & TIFF_NOBITREV) == 0)
270 
271  if (cc > 0 &&
272  !TIFFAppendToStrip(tif, strip, (uint8*) data, cc))
273  return ((tmsize_t) -1);
274  return (cc);
275  }
276 
277  sample = (uint16)(strip / td->td_stripsperimage);
278  if (!(*tif->tif_preencode)(tif, sample))
279  return ((tmsize_t) -1);
280 
281  /* swab if needed - note that source buffer will be altered */
282  tif->tif_postdecode( tif, (uint8*) data, cc );
283 
284  if (!(*tif->tif_encodestrip)(tif, (uint8*) data, cc, sample))
285  return ((tmsize_t) -1);
286  if (!(*tif->tif_postencode)(tif))
287  return ((tmsize_t) -1);
288  if (!isFillOrder(tif, td->td_fillorder) &&
289  (tif->tif_flags & TIFF_NOBITREV) == 0)
291  if (tif->tif_rawcc > 0 &&
292  !TIFFAppendToStrip(tif, strip, tif->tif_rawdata, tif->tif_rawcc))
293  return ((tmsize_t) -1);
294  tif->tif_rawcc = 0;
295  tif->tif_rawcp = tif->tif_rawdata;
296  return (cc);
297 }
298 
299 /*
300  * Write the supplied data to the specified strip.
301  *
302  * NB: Image length must be setup before writing.
303  */
304 tmsize_t
306 {
307  static const char module[] = "TIFFWriteRawStrip";
308  TIFFDirectory *td = &tif->tif_dir;
309 
310  if (!WRITECHECKSTRIPS(tif, module))
311  return ((tmsize_t) -1);
312  /*
313  * Check strip array to make sure there's space.
314  * We don't support dynamically growing files that
315  * have data organized in separate bitplanes because
316  * it's too painful. In that case we require that
317  * the imagelength be set properly before the first
318  * write (so that the strips array will be fully
319  * allocated above).
320  */
321  if (strip >= td->td_nstrips) {
324  "Can not grow image by strips when using separate planes");
325  return ((tmsize_t) -1);
326  }
327  /*
328  * Watch out for a growing image. The value of
329  * strips/image will initially be 1 (since it
330  * can't be deduced until the imagelength is known).
331  */
332  if (strip >= td->td_stripsperimage)
333  td->td_stripsperimage =
335  if (!TIFFGrowStrips(tif, 1, module))
336  return ((tmsize_t) -1);
337  }
338  tif->tif_curstrip = strip;
339  if (td->td_stripsperimage == 0) {
340  TIFFErrorExt(tif->tif_clientdata, 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*) data, cc) ?
345  cc : (tmsize_t) -1);
346 }
347 
348 /*
349  * Write and compress a tile of data. The
350  * tile is selected by the (x,y,z,s) coordinates.
351  */
352 tmsize_t
354 {
355  if (!TIFFCheckTile(tif, x, y, z, s))
356  return ((tmsize_t)(-1));
357  /*
358  * NB: A tile size of -1 is used instead of tif_tilesize knowing
359  * that TIFFWriteEncodedTile will clamp this to the tile size.
360  * This is done because the tile size may not be defined until
361  * after the output buffer is setup in TIFFWriteBufferSetup.
362  */
363  return (TIFFWriteEncodedTile(tif,
364  TIFFComputeTile(tif, x, y, z, s), buf, (tmsize_t)(-1)));
365 }
366 
367 /*
368  * Encode the supplied data and write it to the
369  * specified tile. There must be space for the
370  * data. The function clamps individual writes
371  * to a tile to the tile size, but does not (and
372  * can not) check that multiple writes to the same
373  * tile do not write more than tile size data.
374  *
375  * NB: Image length must be setup before writing; this
376  * interface does not support automatically growing
377  * the image on each write (as TIFFWriteScanline does).
378  */
379 tmsize_t
381 {
382  static const char module[] = "TIFFWriteEncodedTile";
383  TIFFDirectory *td;
384  uint16 sample;
385  uint32 howmany32;
386 
387  if (!WRITECHECKTILES(tif, module))
388  return ((tmsize_t)(-1));
389  td = &tif->tif_dir;
390  if (tile >= td->td_nstrips) {
391  TIFFErrorExt(tif->tif_clientdata, module, "Tile %lu out of range, max %lu",
392  (unsigned long) tile, (unsigned long) td->td_nstrips);
393  return ((tmsize_t)(-1));
394  }
395  /*
396  * Handle delayed allocation of data buffer. This
397  * permits it to be sized more intelligently (using
398  * directory information).
399  */
400  if (!BUFFERCHECK(tif))
401  return ((tmsize_t)(-1));
402 
403  tif->tif_flags |= TIFF_BUF4WRITE;
404  tif->tif_curtile = tile;
405 
406  if( td->td_stripbytecount[tile] > 0 )
407  {
408  /* Make sure that at the first attempt of rewriting the tile, we will have */
409  /* more bytes available in the output buffer than the previous byte count, */
410  /* so that TIFFAppendToStrip() will detect the overflow when it is called the first */
411  /* time if the new compressed tile is bigger than the older one. (GDAL #4771) */
412  if( tif->tif_rawdatasize <= (tmsize_t) td->td_stripbytecount[tile] )
413  {
414  if( !(TIFFWriteBufferSetup(tif, NULL,
415  (tmsize_t)TIFFroundup_64((uint64)(td->td_stripbytecount[tile] + 1), 1024))) )
416  return ((tmsize_t)(-1));
417  }
418 
419  /* Force TIFFAppendToStrip() to consider placing data at end
420  of file. */
421  tif->tif_curoff = 0;
422  }
423 
424  tif->tif_rawcc = 0;
425  tif->tif_rawcp = tif->tif_rawdata;
426 
427  /*
428  * Compute tiles per row & per column to compute
429  * current row and column
430  */
431  howmany32=TIFFhowmany_32(td->td_imagelength, td->td_tilelength);
432  if (howmany32 == 0) {
433  TIFFErrorExt(tif->tif_clientdata,module,"Zero tiles");
434  return ((tmsize_t)(-1));
435  }
436  tif->tif_row = (tile % howmany32) * td->td_tilelength;
437  howmany32=TIFFhowmany_32(td->td_imagewidth, td->td_tilewidth);
438  if (howmany32 == 0) {
439  TIFFErrorExt(tif->tif_clientdata,module,"Zero tiles");
440  return ((tmsize_t)(-1));
441  }
442  tif->tif_col = (tile % howmany32) * td->td_tilewidth;
443 
444  if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
445  if (!(*tif->tif_setupencode)(tif))
446  return ((tmsize_t)(-1));
447  tif->tif_flags |= TIFF_CODERSETUP;
448  }
449  tif->tif_flags &= ~TIFF_POSTENCODE;
450 
451  /*
452  * Clamp write amount to the tile size. This is mostly
453  * done so that callers can pass in some large number
454  * (e.g. -1) and have the tile size used instead.
455  */
456  if ( cc < 1 || cc > tif->tif_tilesize)
457  cc = tif->tif_tilesize;
458 
459  /* shortcut to avoid an extra memcpy() */
460  if( td->td_compression == COMPRESSION_NONE )
461  {
462  /* swab if needed - note that source buffer will be altered */
463  tif->tif_postdecode( tif, (uint8*) data, cc );
464 
465  if (!isFillOrder(tif, td->td_fillorder) &&
466  (tif->tif_flags & TIFF_NOBITREV) == 0)
468 
469  if (cc > 0 &&
470  !TIFFAppendToStrip(tif, tile, (uint8*) data, cc))
471  return ((tmsize_t) -1);
472  return (cc);
473  }
474 
475  sample = (uint16)(tile/td->td_stripsperimage);
476  if (!(*tif->tif_preencode)(tif, sample))
477  return ((tmsize_t)(-1));
478  /* swab if needed - note that source buffer will be altered */
479  tif->tif_postdecode( tif, (uint8*) data, cc );
480 
481  if (!(*tif->tif_encodetile)(tif, (uint8*) data, cc, sample))
482  return ((tmsize_t) -1);
483  if (!(*tif->tif_postencode)(tif))
484  return ((tmsize_t)(-1));
485  if (!isFillOrder(tif, td->td_fillorder) &&
486  (tif->tif_flags & TIFF_NOBITREV) == 0)
488  if (tif->tif_rawcc > 0 && !TIFFAppendToStrip(tif, tile,
489  tif->tif_rawdata, tif->tif_rawcc))
490  return ((tmsize_t)(-1));
491  tif->tif_rawcc = 0;
492  tif->tif_rawcp = tif->tif_rawdata;
493  return (cc);
494 }
495 
496 /*
497  * Write the supplied data to the specified strip.
498  * There must be space for the data; we don't check
499  * if strips overlap!
500  *
501  * NB: Image length must be setup before writing; this
502  * interface does not support automatically growing
503  * the image on each write (as TIFFWriteScanline does).
504  */
505 tmsize_t
507 {
508  static const char module[] = "TIFFWriteRawTile";
509 
510  if (!WRITECHECKTILES(tif, module))
511  return ((tmsize_t)(-1));
512  if (tile >= tif->tif_dir.td_nstrips) {
513  TIFFErrorExt(tif->tif_clientdata, module, "Tile %lu out of range, max %lu",
514  (unsigned long) tile,
515  (unsigned long) tif->tif_dir.td_nstrips);
516  return ((tmsize_t)(-1));
517  }
518  return (TIFFAppendToStrip(tif, tile, (uint8*) data, cc) ?
519  cc : (tmsize_t)(-1));
520 }
521 
522 #define isUnspecified(tif, f) \
523  (TIFFFieldSet(tif,f) && (tif)->tif_dir.td_imagelength == 0)
524 
525 int
527 {
528  TIFFDirectory* td = &tif->tif_dir;
529 
530  if (isTiled(tif))
531  td->td_stripsperimage =
534  else
535  td->td_stripsperimage =
538  td->td_nstrips = td->td_stripsperimage;
541  td->td_stripoffset = (uint64 *)
543  "for \"StripOffsets\" array");
544  td->td_stripbytecount = (uint64 *)
546  "for \"StripByteCounts\" array");
547  if (td->td_stripoffset == NULL || td->td_stripbytecount == NULL)
548  return (0);
549  /*
550  * Place data at the end-of-file
551  * (by setting offsets to zero).
552  */
557  return (1);
558 }
559 #undef isUnspecified
560 
561 /*
562  * Verify file is writable and that the directory
563  * information is setup properly. In doing the latter
564  * we also "freeze" the state of the directory so
565  * that important information is not changed.
566  */
567 int
568 TIFFWriteCheck(TIFF* tif, int tiles, const char* module)
569 {
570  if (tif->tif_mode == O_RDONLY) {
571  TIFFErrorExt(tif->tif_clientdata, module, "File not open for writing");
572  return (0);
573  }
574  if (tiles ^ isTiled(tif)) {
575  TIFFErrorExt(tif->tif_clientdata, module, tiles ?
576  "Can not write tiles to a stripped image" :
577  "Can not write scanlines to a tiled image");
578  return (0);
579  }
580 
581  _TIFFFillStriles( tif );
582 
583  /*
584  * On the first write verify all the required information
585  * has been setup and initialize any data structures that
586  * had to wait until directory information was set.
587  * Note that a lot of our work is assumed to remain valid
588  * because we disallow any of the important parameters
589  * from changing after we start writing (i.e. once
590  * TIFF_BEENWRITING is set, TIFFSetField will only allow
591  * the image's length to be changed).
592  */
593  if (!TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS)) {
595  "Must set \"ImageWidth\" before writing data");
596  return (0);
597  }
598  if (tif->tif_dir.td_samplesperpixel == 1) {
599  /*
600  * Planarconfiguration is irrelevant in case of single band
601  * images and need not be included. We will set it anyway,
602  * because this field is used in other parts of library even
603  * in the single band case.
604  */
605  if (!TIFFFieldSet(tif, FIELD_PLANARCONFIG))
607  } else {
608  if (!TIFFFieldSet(tif, FIELD_PLANARCONFIG)) {
610  "Must set \"PlanarConfiguration\" before writing data");
611  return (0);
612  }
613  }
614  if (tif->tif_dir.td_stripoffset == NULL && !TIFFSetupStrips(tif)) {
615  tif->tif_dir.td_nstrips = 0;
616  TIFFErrorExt(tif->tif_clientdata, module, "No space for %s arrays",
617  isTiled(tif) ? "tile" : "strip");
618  return (0);
619  }
620  if (isTiled(tif))
621  {
622  tif->tif_tilesize = TIFFTileSize(tif);
623  if (tif->tif_tilesize == 0)
624  return (0);
625  }
626  else
627  tif->tif_tilesize = (tmsize_t)(-1);
629  if (tif->tif_scanlinesize == 0)
630  return (0);
631  tif->tif_flags |= TIFF_BEENWRITING;
632  return (1);
633 }
634 
635 /*
636  * Setup the raw data buffer used for encoding.
637  */
638 int
640 {
641  static const char module[] = "TIFFWriteBufferSetup";
642 
643  if (tif->tif_rawdata) {
644  if (tif->tif_flags & TIFF_MYBUFFER) {
645  _TIFFfree(tif->tif_rawdata);
646  tif->tif_flags &= ~TIFF_MYBUFFER;
647  }
648  tif->tif_rawdata = NULL;
649  }
650  if (size == (tmsize_t)(-1)) {
651  size = (isTiled(tif) ?
652  tif->tif_tilesize : TIFFStripSize(tif));
653  /*
654  * Make raw data buffer at least 8K
655  */
656  if (size < 8*1024)
657  size = 8*1024;
658  bp = NULL; /* NB: force malloc */
659  }
660  if (bp == NULL) {
661  bp = _TIFFmalloc(size);
662  if (bp == NULL) {
663  TIFFErrorExt(tif->tif_clientdata, module, "No space for output buffer");
664  return (0);
665  }
666  tif->tif_flags |= TIFF_MYBUFFER;
667  } else
668  tif->tif_flags &= ~TIFF_MYBUFFER;
669  tif->tif_rawdata = (uint8*) bp;
670  tif->tif_rawdatasize = size;
671  tif->tif_rawcc = 0;
672  tif->tif_rawcp = tif->tif_rawdata;
673  tif->tif_flags |= TIFF_BUFFERSETUP;
674  return (1);
675 }
676 
677 /*
678  * Grow the strip data structures by delta strips.
679  */
680 static int
681 TIFFGrowStrips(TIFF* tif, uint32 delta, const char* module)
682 {
683  TIFFDirectory *td = &tif->tif_dir;
684  uint64* new_stripoffset;
685  uint64* new_stripbytecount;
686 
688  new_stripoffset = (uint64*)_TIFFrealloc(td->td_stripoffset,
689  (td->td_nstrips + delta) * sizeof (uint64));
690  new_stripbytecount = (uint64*)_TIFFrealloc(td->td_stripbytecount,
691  (td->td_nstrips + delta) * sizeof (uint64));
692  if (new_stripoffset == NULL || new_stripbytecount == NULL) {
693  if (new_stripoffset)
694  _TIFFfree(new_stripoffset);
695  if (new_stripbytecount)
696  _TIFFfree(new_stripbytecount);
697  td->td_nstrips = 0;
698  TIFFErrorExt(tif->tif_clientdata, module, "No space to expand strip arrays");
699  return (0);
700  }
701  td->td_stripoffset = new_stripoffset;
702  td->td_stripbytecount = new_stripbytecount;
704  0, delta*sizeof (uint64));
706  0, delta*sizeof (uint64));
707  td->td_nstrips += delta;
708  tif->tif_flags |= TIFF_DIRTYDIRECT;
709 
710  return (1);
711 }
712 
713 /*
714  * Append the data to the specified strip.
715  */
716 static int
718 {
719  static const char module[] = "TIFFAppendToStrip";
720  TIFFDirectory *td = &tif->tif_dir;
721  uint64 m;
722  int64 old_byte_count = -1;
723 
724  if (td->td_stripoffset[strip] == 0 || tif->tif_curoff == 0) {
725  assert(td->td_nstrips > 0);
726 
727  if( td->td_stripbytecount[strip] != 0
728  && td->td_stripoffset[strip] != 0
729  && td->td_stripbytecount[strip] >= (uint64) cc )
730  {
731  /*
732  * There is already tile data on disk, and the new tile
733  * data we have will fit in the same space. The only
734  * aspect of this that is risky is that there could be
735  * more data to append to this strip before we are done
736  * depending on how we are getting called.
737  */
738  if (!SeekOK(tif, td->td_stripoffset[strip])) {
740  "Seek error at scanline %lu",
741  (unsigned long)tif->tif_row);
742  return (0);
743  }
744  }
745  else
746  {
747  /*
748  * Seek to end of file, and set that as our location to
749  * write this strip.
750  */
751  td->td_stripoffset[strip] = TIFFSeekFile(tif, 0, SEEK_END);
752  tif->tif_flags |= TIFF_DIRTYSTRIP;
753  }
754 
755  tif->tif_curoff = td->td_stripoffset[strip];
756 
757  /*
758  * We are starting a fresh strip/tile, so set the size to zero.
759  */
760  old_byte_count = td->td_stripbytecount[strip];
761  td->td_stripbytecount[strip] = 0;
762  }
763 
764  m = tif->tif_curoff+cc;
765  if (!(tif->tif_flags&TIFF_BIGTIFF))
766  m = (uint32)m;
767  if ((m<tif->tif_curoff)||(m<(uint64)cc))
768  {
769  TIFFErrorExt(tif->tif_clientdata, module, "Maximum TIFF file size exceeded");
770  return (0);
771  }
772  if (!WriteOK(tif, data, cc)) {
773  TIFFErrorExt(tif->tif_clientdata, module, "Write error at scanline %lu",
774  (unsigned long) tif->tif_row);
775  return (0);
776  }
777  tif->tif_curoff = m;
778  td->td_stripbytecount[strip] += cc;
779 
780  if( (int64) td->td_stripbytecount[strip] != old_byte_count )
781  tif->tif_flags |= TIFF_DIRTYSTRIP;
782 
783  return (1);
784 }
785 
786 /*
787  * Internal version of TIFFFlushData that can be
788  * called by ``encodestrip routines'' w/o concern
789  * for infinite recursion.
790  */
791 int
793 {
794  if (tif->tif_rawcc > 0 && tif->tif_flags & TIFF_BUF4WRITE ) {
795  if (!isFillOrder(tif, tif->tif_dir.td_fillorder) &&
796  (tif->tif_flags & TIFF_NOBITREV) == 0)
798  tif->tif_rawcc);
799  if (!TIFFAppendToStrip(tif,
800  isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip,
801  tif->tif_rawdata, tif->tif_rawcc))
802  {
803  /* We update those variables even in case of error since there's */
804  /* code that doesn't really check the return code of this */
805  /* function */
806  tif->tif_rawcc = 0;
807  tif->tif_rawcp = tif->tif_rawdata;
808  return (0);
809  }
810  tif->tif_rawcc = 0;
811  tif->tif_rawcp = tif->tif_rawdata;
812  }
813  return (1);
814 }
815 
816 /*
817  * Set the current write offset. This should only be
818  * used to set the offset to a known previous location
819  * (very carefully), or to 0 so that the next write gets
820  * appended to the end of the file.
821  */
822 void
824 {
825  tif->tif_curoff = off;
826 }
827 
828 /* vim: set ts=8 sts=8 sw=8 noet: */
829 /*
830  * Local Variables:
831  * mode: c
832  * c-basic-offset: 8
833  * fill-column: 78
834  * End:
835  */
unsigned long long uint64
Definition: platform.h:18
#define TIFF_BEENWRITING
Definition: tiffiop.h:112
uint8 * tif_rawcp
Definition: tiffiop.h:183
int TIFFCheckTile(TIFF *tif, uint32 x, uint32 y, uint32 z, uint16 s)
Definition: tif_tile.c:74
void _TIFFmemset(void *p, int v, tmsize_t c)
Definition: tif_unix.c:338
return
Definition: dirsup.c:529
uint32 TIFFComputeTile(TIFF *tif, uint32 x, uint32 y, uint32 z, uint16 s)
Definition: tif_tile.c:37
uint32 TIFFNumberOfStrips(TIFF *tif)
Definition: tif_strip.c:60
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList
int TIFFSetupStrips(TIFF *tif)
Definition: tif_write.c:526
#define TIFFhowmany_32(x, y)
Definition: tiffiop.h:248
#define FIELD_STRIPOFFSETS
Definition: tif_dir.h:158
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
TIFFCodeMethod tif_encodestrip
Definition: tiffiop.h:167
#define WriteOK(tif, buf, size)
Definition: tiffiop.h:243
#define FIELD_IMAGEDIMENSIONS
Definition: tif_dir.h:137
unsigned int uint32
Definition: types.h:32
#define TIFFSeekFile(tif, off, whence)
Definition: tiffiop.h:221
uint64 toff_t
Definition: tiffio.h:66
TIFFCodeMethod tif_encoderow
Definition: tiffiop.h:165
uint32 tif_curstrip
Definition: tiffiop.h:145
static int TIFFGrowStrips(TIFF *tif, uint32 delta, const char *module)
Definition: tif_write.c:681
int TIFFWriteBufferSetup(TIFF *tif, void *bp, tmsize_t size)
Definition: tif_write.c:639
#define assert(x)
Definition: debug.h:53
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
#define WRITECHECKSTRIPS(tif, module)
Definition: tif_write.c:36
uint8 * tif_rawdata
Definition: tiffiop.h:179
tmsize_t tif_scanlinesize
Definition: tiffiop.h:177
uint64 tif_curoff
Definition: tiffiop.h:146
thandle_t tif_clientdata
Definition: tiffiop.h:191
long long int64
Definition: platform.h:13
uint32 TIFFNumberOfTiles(TIFF *tif)
Definition: tif_tile.c:114
tmsize_t tif_rawcc
Definition: tiffiop.h:184
tmsize_t tif_tilesize
Definition: tiffiop.h:154
int TIFFWriteScanline(TIFF *tif, void *buf, uint32 row, uint16 sample)
Definition: tif_write.c:48
#define TIFF_DIRTYDIRECT
Definition: tiffiop.h:109
const GLfloat * m
Definition: glext.h:10848
Definition: tiffiop.h:102
uint32 td_tilelength
Definition: tif_dir.h:72
tmsize_t TIFFStripSize(TIFF *tif)
Definition: tif_strip.c:211
#define TIFFSetFieldBit(tif, field)
Definition: tif_dir.h:193
#define TIFF_BIGTIFF
Definition: tiffiop.h:125
#define FIELD_STRIPBYTECOUNTS
Definition: tif_dir.h:157
TIFF_SSIZE_T tmsize_t
Definition: tiffio.h:65
int TIFFFlushData(TIFF *tif)
Definition: tif_flush.c:98
void * _TIFFCheckMalloc(TIFF *tif, tmsize_t nmemb, tmsize_t elem_size, const char *what)
Definition: tif_aux.c:85
uint32 td_stripsperimage
Definition: tif_dir.h:98
int tif_mode
Definition: tiffiop.h:105
GLdouble GLdouble z
Definition: glext.h:5874
uint32 tif_flags
Definition: tiffiop.h:106
smooth NULL
Definition: ftsmooth.c:416
#define FIELD_PLANARCONFIG
Definition: tif_dir.h:154
uint16 td_planarconfig
Definition: tif_dir.h:88
TIFFCodeMethod tif_encodetile
Definition: tiffiop.h:169
#define TIFF_POSTENCODE
Definition: tiffiop.h:118
void * _TIFFmalloc(tmsize_t s)
Definition: tif_unix.c:309
TIFFSeekMethod tif_seek
Definition: tiffiop.h:171
TIFFPreMethod tif_preencode
Definition: tiffiop.h:162
#define TIFF_BUF4WRITE
Definition: tiffiop.h:126
uint32 td_nstrips
Definition: tif_dir.h:99
GLsizeiptr size
Definition: glext.h:5919
TIFFBoolMethod tif_postencode
Definition: tiffiop.h:163
if(!(yy_init))
Definition: macro.lex.yy.c:714
uint32 td_imagelength
Definition: tif_dir.h:71
TIFFPostMethod tif_postdecode
Definition: tiffiop.h:198
tmsize_t TIFFWriteEncodedTile(TIFF *tif, uint32 tile, void *data, tmsize_t cc)
Definition: tif_write.c:380
unsigned char uint8
Definition: types.h:28
void TIFFErrorExt(thandle_t fd, const char *module, const char *fmt,...)
Definition: tif_error.c:65
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
tmsize_t tif_rawdatasize
Definition: tiffiop.h:180
#define TIFFFieldSet(tif, field)
Definition: tif_dir.h:192
uint16 td_fillorder
Definition: tif_dir.h:79
tmsize_t TIFFWriteRawTile(TIFF *tif, uint32 tile, void *data, tmsize_t cc)
Definition: tif_write.c:506
uint64 * td_stripoffset
Definition: tif_dir.h:100
#define FIELD_ROWSPERSTRIP
Definition: tif_dir.h:151
#define TIFF_DIRTYSTRIP
Definition: tiffiop.h:127
void * _TIFFrealloc(void *p, tmsize_t s)
Definition: tif_unix.c:332
uint32 tif_curtile
Definition: tiffiop.h:153
#define COMPRESSION_NONE
Definition: tiff.h:158
uint32 td_tilewidth
Definition: tif_dir.h:72
#define TIFF_NOBITREV
Definition: tiffiop.h:114
#define PLANARCONFIG_SEPARATE
Definition: tiff.h:241
uint64 * td_stripbytecount
Definition: tif_dir.h:101
GLdouble s
Definition: gl.h:2039
#define isTiled(tif)
Definition: tiffiop.h:213
#define TIFF_BUFFERSETUP
Definition: tiffiop.h:110
#define TIFF_CODERSETUP
Definition: tiffiop.h:111
int TIFFWriteCheck(TIFF *tif, int tiles, const char *module)
Definition: tif_write.c:568
uint32_t cc
Definition: isohybrid.c:75
void TIFFSetWriteOffset(TIFF *tif, toff_t off)
Definition: tif_write.c:823
uint32 td_rowsperstrip
Definition: tif_dir.h:82
uint32 tif_row
Definition: tiffiop.h:143
static int TIFFAppendToStrip(TIFF *tif, uint32 strip, uint8 *data, tmsize_t cc)
Definition: tif_write.c:717
tmsize_t TIFFWriteEncodedStrip(TIFF *tif, uint32 strip, void *data, tmsize_t cc)
Definition: tif_write.c:187
tmsize_t TIFFScanlineSize(TIFF *tif)
Definition: tif_strip.c:330
unsigned short uint16
Definition: types.h:30
tmsize_t TIFFWriteRawStrip(TIFF *tif, uint32 strip, void *data, tmsize_t cc)
Definition: tif_write.c:305
TIFFDirectory tif_dir
Definition: tiffiop.h:135
#define isFillOrder(tif, o)
Definition: tiffiop.h:215
#define FIELD_TILEDIMENSIONS
Definition: tif_dir.h:138
#define SeekOK(tif, off)
Definition: tiffiop.h:240
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
tmsize_t TIFFTileSize(TIFF *tif)
Definition: tif_tile.c:272
#define TIFFroundup_64(x, y)
Definition: tiffiop.h:259
void TIFFReverseBits(uint8 *cp, tmsize_t n)
Definition: tif_swab.c:284
#define SEEK_END
Definition: cabinet.c:27
uint16 td_samplesperpixel
Definition: tif_dir.h:81
uint16 td_compression
Definition: tif_dir.h:76
void _TIFFfree(void *p)
Definition: tif_unix.c:326
#define BUFFERCHECK(tif)
Definition: tif_write.c:40
uint32 tif_col
Definition: tiffiop.h:152
#define isUnspecified(tif, f)
Definition: tif_write.c:522
tmsize_t TIFFWriteTile(TIFF *tif, void *buf, uint32 x, uint32 y, uint32 z, uint16 s)
Definition: tif_write.c:353
uint32 td_imagewidth
Definition: tif_dir.h:71
static SERVICE_STATUS status
Definition: service.c:31
TIFFBoolMethod tif_setupencode
Definition: tiffiop.h:160
int TIFFFlushData1(TIFF *tif)
Definition: tif_write.c:792
#define TIFF_MYBUFFER
Definition: tiffiop.h:115
#define WRITECHECKTILES(tif, module)
Definition: tif_write.c:38
#define PLANARCONFIG_CONTIG
Definition: tiff.h:240
int _TIFFFillStriles(TIFF *tif)
Definition: tif_dirread.c:5812
struct png_info_def *typedef unsigned char **typedef struct png_info_def *typedef struct png_info_def *typedef struct png_info_def *typedef unsigned char ** row
Definition: typeof.h:78
#define O_RDONLY
Definition: acwin.h:82
off
Definition: i386-dis.c:3909
Definition: ps.c:97