~paparazzi-uav/paparazzi/v5.0-manual

« back to all changes in this revision

Viewing changes to sw/ext/opencv_bebop/opencv/3rdparty/libtiff/tif_stream.cxx

  • Committer: Paparazzi buildbot
  • Date: 2016-05-18 15:00:29 UTC
  • Revision ID: felix.ruess+docbot@gmail.com-20160518150029-e8lgzi5kvb4p7un9
Manual import commit 4b8bbb730080dac23cf816b98908dacfabe2a8ec from v5.0 branch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: tif_stream.cxx,v 1.11 2010-12-11 23:12:29 faxguy Exp $ */
 
2
 
 
3
/*
 
4
 * Copyright (c) 1988-1996 Sam Leffler
 
5
 * Copyright (c) 1991-1996 Silicon Graphics, Inc.
 
6
 *
 
7
 * Permission to use, copy, modify, distribute, and sell this software and
 
8
 * its documentation for any purpose is hereby granted without fee, provided
 
9
 * that (i) the above copyright notices and this permission notice appear in
 
10
 * all copies of the software and related documentation, and (ii) the names of
 
11
 * Sam Leffler and Silicon Graphics may not be used in any advertising or
 
12
 * publicity relating to the software without the specific, prior written
 
13
 * permission of Sam Leffler and Silicon Graphics.
 
14
 *
 
15
 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
 
16
 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
 
17
 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
 
18
 *
 
19
 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
 
20
 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
 
21
 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 
22
 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
 
23
 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
 
24
 * OF THIS SOFTWARE.
 
25
 */
 
26
 
 
27
/*
 
28
 * TIFF Library UNIX-specific Routines.
 
29
 */
 
30
#include "tiffiop.h"
 
31
#include "tiffio.hxx"
 
32
#include <iostream>
 
33
 
 
34
#ifndef __VMS
 
35
using namespace std;
 
36
#endif
 
37
 
 
38
/*
 
39
  ISO C++ uses a 'std::streamsize' type to define counts.  This makes
 
40
  it similar to, (but perhaps not the same as) size_t.
 
41
 
 
42
  The std::ios::pos_type is used to represent stream positions as used
 
43
  by tellg(), tellp(), seekg(), and seekp().  This makes it similar to
 
44
  (but perhaps not the same as) 'off_t'.  The std::ios::streampos type
 
45
  is used for character streams, but is documented to not be an
 
46
  integral type anymore, so it should *not* be assigned to an integral
 
47
  type.
 
48
 
 
49
  The std::ios::off_type is used to specify relative offsets needed by
 
50
  the variants of seekg() and seekp() which accept a relative offset
 
51
  argument.
 
52
 
 
53
  Useful prototype knowledge:
 
54
 
 
55
  Obtain read position
 
56
    ios::pos_type basic_istream::tellg()
 
57
 
 
58
  Set read position
 
59
    basic_istream& basic_istream::seekg(ios::pos_type)
 
60
    basic_istream& basic_istream::seekg(ios::off_type, ios_base::seekdir)
 
61
 
 
62
  Read data
 
63
    basic_istream& istream::read(char *str, streamsize count)
 
64
 
 
65
  Number of characters read in last unformatted read
 
66
    streamsize istream::gcount();
 
67
 
 
68
  Obtain write position
 
69
    ios::pos_type basic_ostream::tellp()
 
70
 
 
71
  Set write position
 
72
    basic_ostream& basic_ostream::seekp(ios::pos_type)
 
73
    basic_ostream& basic_ostream::seekp(ios::off_type, ios_base::seekdir)
 
74
 
 
75
  Write data
 
76
    basic_ostream& ostream::write(const char *str, streamsize count)
 
77
*/
 
78
 
 
79
struct tiffis_data;
 
80
struct tiffos_data;
 
81
 
 
82
extern "C" {
 
83
 
 
84
    static tmsize_t _tiffosReadProc(thandle_t, void*, tmsize_t);
 
85
    static tmsize_t _tiffisReadProc(thandle_t fd, void* buf, tmsize_t size);
 
86
    static tmsize_t _tiffosWriteProc(thandle_t fd, void* buf, tmsize_t size);
 
87
    static tmsize_t _tiffisWriteProc(thandle_t, void*, tmsize_t);
 
88
    static uint64   _tiffosSeekProc(thandle_t fd, uint64 off, int whence);
 
89
    static uint64   _tiffisSeekProc(thandle_t fd, uint64 off, int whence);
 
90
    static uint64   _tiffosSizeProc(thandle_t fd);
 
91
    static uint64   _tiffisSizeProc(thandle_t fd);
 
92
    static int      _tiffosCloseProc(thandle_t fd);
 
93
    static int      _tiffisCloseProc(thandle_t fd);
 
94
    static int  _tiffDummyMapProc(thandle_t , void** base, toff_t* size );
 
95
    static void     _tiffDummyUnmapProc(thandle_t , void* base, toff_t size );
 
96
    static TIFF*    _tiffStreamOpen(const char* name, const char* mode, void *fd);
 
97
 
 
98
struct tiffis_data
 
99
{
 
100
    istream     *stream;
 
101
        ios::pos_type start_pos;
 
102
};
 
103
 
 
104
struct tiffos_data
 
105
{
 
106
    ostream     *stream;
 
107
    ios::pos_type start_pos;
 
108
};
 
109
 
 
110
static tmsize_t
 
111
_tiffosReadProc(thandle_t, void*, tmsize_t)
 
112
{
 
113
        return 0;
 
114
}
 
115
 
 
116
static tmsize_t
 
117
_tiffisReadProc(thandle_t fd, void* buf, tmsize_t size)
 
118
{
 
119
        tiffis_data     *data = reinterpret_cast<tiffis_data *>(fd);
 
120
 
 
121
        // Verify that type does not overflow.
 
122
        streamsize request_size = size;
 
123
        if (static_cast<tmsize_t>(request_size) != size)
 
124
          return static_cast<tmsize_t>(-1);
 
125
 
 
126
        data->stream->read((char *) buf, request_size);
 
127
 
 
128
        return static_cast<tmsize_t>(data->stream->gcount());
 
129
}
 
130
 
 
131
static tmsize_t
 
132
_tiffosWriteProc(thandle_t fd, void* buf, tmsize_t size)
 
133
{
 
134
    tiffos_data *data = reinterpret_cast<tiffos_data *>(fd);
 
135
    ostream             *os = data->stream;
 
136
    ios::pos_type       pos = os->tellp();
 
137
 
 
138
        // Verify that type does not overflow.
 
139
        streamsize request_size = size;
 
140
        if (static_cast<tmsize_t>(request_size) != size)
 
141
          return static_cast<tmsize_t>(-1);
 
142
 
 
143
    os->write(reinterpret_cast<const char *>(buf), request_size);
 
144
 
 
145
    return static_cast<tmsize_t>(os->tellp() - pos);
 
146
}
 
147
 
 
148
static tmsize_t
 
149
_tiffisWriteProc(thandle_t, void*, tmsize_t)
 
150
{
 
151
    return 0;
 
152
}
 
153
 
 
154
static uint64
 
155
_tiffosSeekProc(thandle_t fd, uint64 off, int whence)
 
156
{
 
157
    tiffos_data *data = reinterpret_cast<tiffos_data *>(fd);
 
158
    ostream             *os = data->stream;
 
159
 
 
160
    // if the stream has already failed, don't do anything
 
161
    if( os->fail() )
 
162
        return static_cast<uint64>(-1);
 
163
 
 
164
    switch(whence) {
 
165
    case SEEK_SET:
 
166
        {
 
167
            // Compute 64-bit offset
 
168
            uint64 new_offset = static_cast<uint64>(data->start_pos) + off;
 
169
 
 
170
            // Verify that value does not overflow
 
171
            ios::off_type offset = static_cast<ios::off_type>(new_offset);
 
172
            if (static_cast<uint64>(offset) != new_offset)
 
173
                return static_cast<uint64>(-1);
 
174
 
 
175
            os->seekp(offset, ios::beg);
 
176
        break;
 
177
        }
 
178
    case SEEK_CUR:
 
179
        {
 
180
            // Verify that value does not overflow
 
181
            ios::off_type offset = static_cast<ios::off_type>(off);
 
182
            if (static_cast<uint64>(offset) != off)
 
183
                return static_cast<uint64>(-1);
 
184
 
 
185
            os->seekp(offset, ios::cur);
 
186
            break;
 
187
        }
 
188
    case SEEK_END:
 
189
        {
 
190
            // Verify that value does not overflow
 
191
            ios::off_type offset = static_cast<ios::off_type>(off);
 
192
            if (static_cast<uint64>(offset) != off)
 
193
                return static_cast<uint64>(-1);
 
194
 
 
195
            os->seekp(offset, ios::end);
 
196
            break;
 
197
        }
 
198
    }
 
199
 
 
200
    // Attempt to workaround problems with seeking past the end of the
 
201
    // stream.  ofstream doesn't have a problem with this but
 
202
    // ostrstream/ostringstream does. In that situation, add intermediate
 
203
    // '\0' characters.
 
204
    if( os->fail() ) {
 
205
#ifdef __VMS
 
206
        int             old_state;
 
207
#else
 
208
        ios::iostate    old_state;
 
209
#endif
 
210
        ios::pos_type   origin;
 
211
 
 
212
        old_state = os->rdstate();
 
213
        // reset the fail bit or else tellp() won't work below
 
214
        os->clear(os->rdstate() & ~ios::failbit);
 
215
        switch( whence ) {
 
216
            case SEEK_SET:
 
217
                        default:
 
218
                origin = data->start_pos;
 
219
                break;
 
220
            case SEEK_CUR:
 
221
                origin = os->tellp();
 
222
                break;
 
223
            case SEEK_END:
 
224
                os->seekp(0, ios::end);
 
225
                origin = os->tellp();
 
226
                break;
 
227
        }
 
228
        // restore original stream state
 
229
        os->clear(old_state);
 
230
 
 
231
        // only do something if desired seek position is valid
 
232
        if( (static_cast<uint64>(origin) + off) > static_cast<uint64>(data->start_pos) ) {
 
233
            uint64      num_fill;
 
234
 
 
235
            // clear the fail bit
 
236
            os->clear(os->rdstate() & ~ios::failbit);
 
237
 
 
238
            // extend the stream to the expected size
 
239
            os->seekp(0, ios::end);
 
240
            num_fill = (static_cast<uint64>(origin)) + off - os->tellp();
 
241
            for( uint64 i = 0; i < num_fill; i++ )
 
242
                os->put('\0');
 
243
 
 
244
            // retry the seek
 
245
            os->seekp(static_cast<ios::off_type>(static_cast<uint64>(origin) + off), ios::beg);
 
246
        }
 
247
    }
 
248
 
 
249
    return static_cast<uint64>(os->tellp());
 
250
}
 
251
 
 
252
static uint64
 
253
_tiffisSeekProc(thandle_t fd, uint64 off, int whence)
 
254
{
 
255
    tiffis_data *data = reinterpret_cast<tiffis_data *>(fd);
 
256
 
 
257
    switch(whence) {
 
258
    case SEEK_SET:
 
259
        {
 
260
            // Compute 64-bit offset
 
261
            uint64 new_offset = static_cast<uint64>(data->start_pos) + off;
 
262
 
 
263
            // Verify that value does not overflow
 
264
            ios::off_type offset = static_cast<ios::off_type>(new_offset);
 
265
            if (static_cast<uint64>(offset) != new_offset)
 
266
                return static_cast<uint64>(-1);
 
267
 
 
268
            data->stream->seekg(offset, ios::beg);
 
269
            break;
 
270
        }
 
271
    case SEEK_CUR:
 
272
        {
 
273
            // Verify that value does not overflow
 
274
            ios::off_type offset = static_cast<ios::off_type>(off);
 
275
            if (static_cast<uint64>(offset) != off)
 
276
                return static_cast<uint64>(-1);
 
277
 
 
278
            data->stream->seekg(offset, ios::cur);
 
279
            break;
 
280
        }
 
281
    case SEEK_END:
 
282
        {
 
283
            // Verify that value does not overflow
 
284
            ios::off_type offset = static_cast<ios::off_type>(off);
 
285
            if (static_cast<uint64>(offset) != off)
 
286
                return static_cast<uint64>(-1);
 
287
 
 
288
            data->stream->seekg(offset, ios::end);
 
289
            break;
 
290
        }
 
291
    }
 
292
 
 
293
    return (uint64) (data->stream->tellg() - data->start_pos);
 
294
}
 
295
 
 
296
static uint64
 
297
_tiffosSizeProc(thandle_t fd)
 
298
{
 
299
    tiffos_data *data = reinterpret_cast<tiffos_data *>(fd);
 
300
    ostream             *os = data->stream;
 
301
    ios::pos_type       pos = os->tellp();
 
302
    ios::pos_type       len;
 
303
 
 
304
    os->seekp(0, ios::end);
 
305
    len = os->tellp();
 
306
    os->seekp(pos);
 
307
 
 
308
    return (uint64) len;
 
309
}
 
310
 
 
311
static uint64
 
312
_tiffisSizeProc(thandle_t fd)
 
313
{
 
314
    tiffis_data *data = reinterpret_cast<tiffis_data *>(fd);
 
315
    ios::pos_type       pos = data->stream->tellg();
 
316
    ios::pos_type       len;
 
317
 
 
318
    data->stream->seekg(0, ios::end);
 
319
    len = data->stream->tellg();
 
320
    data->stream->seekg(pos);
 
321
 
 
322
    return (uint64) len;
 
323
}
 
324
 
 
325
static int
 
326
_tiffosCloseProc(thandle_t fd)
 
327
{
 
328
    // Our stream was not allocated by us, so it shouldn't be closed by us.
 
329
    delete reinterpret_cast<tiffos_data *>(fd);
 
330
    return 0;
 
331
}
 
332
 
 
333
static int
 
334
_tiffisCloseProc(thandle_t fd)
 
335
{
 
336
    // Our stream was not allocated by us, so it shouldn't be closed by us.
 
337
    delete reinterpret_cast<tiffis_data *>(fd);
 
338
    return 0;
 
339
}
 
340
 
 
341
static int
 
342
_tiffDummyMapProc(thandle_t , void** base, toff_t* size )
 
343
{
 
344
    return (0);
 
345
}
 
346
 
 
347
static void
 
348
_tiffDummyUnmapProc(thandle_t , void* base, toff_t size )
 
349
{
 
350
}
 
351
 
 
352
/*
 
353
 * Open a TIFF file descriptor for read/writing.
 
354
 */
 
355
static TIFF*
 
356
_tiffStreamOpen(const char* name, const char* mode, void *fd)
 
357
{
 
358
    TIFF*       tif;
 
359
 
 
360
    if( strchr(mode, 'w') ) {
 
361
        tiffos_data     *data = new tiffos_data;
 
362
        data->stream = reinterpret_cast<ostream *>(fd);
 
363
        data->start_pos = data->stream->tellp();
 
364
 
 
365
        // Open for writing.
 
366
        tif = TIFFClientOpen(name, mode,
 
367
                reinterpret_cast<thandle_t>(data),
 
368
                _tiffosReadProc,
 
369
                                _tiffosWriteProc,
 
370
                _tiffosSeekProc,
 
371
                                _tiffosCloseProc,
 
372
                _tiffosSizeProc,
 
373
                _tiffDummyMapProc,
 
374
                                _tiffDummyUnmapProc);
 
375
    } else {
 
376
        tiffis_data     *data = new tiffis_data;
 
377
        data->stream = reinterpret_cast<istream *>(fd);
 
378
        data->start_pos = data->stream->tellg();
 
379
        // Open for reading.
 
380
        tif = TIFFClientOpen(name, mode,
 
381
                reinterpret_cast<thandle_t>(data),
 
382
                _tiffisReadProc,
 
383
                                _tiffisWriteProc,
 
384
                _tiffisSeekProc,
 
385
                                _tiffisCloseProc,
 
386
                _tiffisSizeProc,
 
387
                _tiffDummyMapProc,
 
388
                                _tiffDummyUnmapProc);
 
389
    }
 
390
 
 
391
    return (tif);
 
392
}
 
393
 
 
394
} /* extern "C" */
 
395
 
 
396
TIFF*
 
397
TIFFStreamOpen(const char* name, ostream *os)
 
398
{
 
399
    // If os is either a ostrstream or ostringstream, and has no data
 
400
    // written to it yet, then tellp() will return -1 which will break us.
 
401
    // We workaround this by writing out a dummy character and
 
402
    // then seek back to the beginning.
 
403
    if( !os->fail() && static_cast<int>(os->tellp()) < 0 ) {
 
404
        *os << '\0';
 
405
        os->seekp(0);
 
406
    }
 
407
 
 
408
    // NB: We don't support mapped files with streams so add 'm'
 
409
    return _tiffStreamOpen(name, "wm", os);
 
410
}
 
411
 
 
412
TIFF*
 
413
TIFFStreamOpen(const char* name, istream *is)
 
414
{
 
415
    // NB: We don't support mapped files with streams so add 'm'
 
416
    return _tiffStreamOpen(name, "rm", is);
 
417
}
 
418
 
 
419
/* vim: set ts=8 sts=8 sw=8 noet: */
 
420
/*
 
421
  Local Variables:
 
422
  mode: c
 
423
  indent-tabs-mode: true
 
424
  c-basic-offset: 8
 
425
  End:
 
426
*/