Coverage Report

Created: 2022-10-31 07:00

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