Coverage Report

Created: 2025-06-22 08:04

/src/LibRaw/libraw/libraw_datastream.h
Line
Count
Source (jump to first uncovered line)
1
/* -*- C -*-
2
 * File: libraw_datastream.h
3
 * Copyright 2008-2024 LibRaw LLC (info@libraw.org)
4
 * Created: Sun Jan 18 13:07:35 2009
5
 *
6
 * LibRaw Data stream interface
7
8
LibRaw is free software; you can redistribute it and/or modify
9
it under the terms of the one of two licenses as you choose:
10
11
1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
12
   (See file LICENSE.LGPL provided in LibRaw distribution archive for details).
13
14
2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
15
   (See file LICENSE.CDDL provided in LibRaw distribution archive for details).
16
17
 */
18
19
#ifndef __LIBRAW_DATASTREAM_H
20
#define __LIBRAW_DATASTREAM_H
21
22
#include <stdio.h>
23
#include <sys/types.h>
24
#include <errno.h>
25
#include <string.h>
26
27
#ifndef __cplusplus
28
29
#else /* __cplusplus */
30
#if defined _WIN32
31
#ifndef LIBRAW_NO_WINSOCK2
32
#ifdef NOMINMAX
33
#define LIBRAW_NO_UNDEF_NOMINMAX
34
#else
35
#define NOMINMAX
36
#endif
37
38
#include <winsock2.h>
39
40
#ifndef LIBRAW_NO_UNDEF_NOMINMAX
41
#undef NOMINMAX /* restore previous mode*/
42
#endif
43
#undef LIBRAW_NO_UNDEF_NOMINMAX
44
#endif
45
#endif
46
/* No unique_ptr on Apple ?? */
47
#if __cplusplus >= 201103L || (defined(_CPPLIB_VER) && _CPPLIB_VER >= 520) ||  \
48
    (defined(_MSC_VER) && _MSVC_LANG >= 201103L)
49
/* OK - use unique_ptr unless LIBRAW_USE_AUTOPTR defined externally*/
50
#else
51
/* Force to use auto_ptr */
52
#ifndef LIBRAW_USE_AUTOPTR
53
#define LIBRAW_USE_AUTOPTR
54
#endif
55
#endif
56
57
#include "libraw_const.h"
58
#include "libraw_types.h"
59
#include <fstream>
60
#include <memory>
61
#include <vector>
62
63
#if defined(_WIN32) && (_MSC_VER) >= 1500
64
#define WIN32SECURECALLS
65
#endif
66
67
#ifdef USE_DNGSDK
68
69
#if defined LIBRAW_WIN32_CALLS
70
#define qWinOS 1
71
#define qMacOS 0
72
#elif defined(__APPLE__)
73
#define qWinOS 0
74
#define qMacOS 1
75
#else
76
/* define OS types for DNG here */
77
#endif
78
#define qDNGXMPDocOps 0
79
#define qDNGUseLibJPEG 1
80
#define qDNGXMPFiles 0
81
#define qDNGExperimental 1
82
#define qDNGThreadSafe 1
83
#include "dng_stream.h"
84
#endif /* DNGSDK */
85
86
#define IOERROR()                                                              \
87
  do                                                                           \
88
  {                                                                            \
89
    throw LIBRAW_EXCEPTION_IO_EOF;                                             \
90
  } while (0)
91
92
class LibRaw_buffer_datastream;
93
class LibRaw_bit_buffer;
94
95
class DllDef LibRaw_abstract_datastream
96
{
97
public:
98
25.6k
  LibRaw_abstract_datastream() { };
99
25.6k
  virtual ~LibRaw_abstract_datastream(void) { }
100
  virtual int valid() = 0;
101
  virtual int read(void *, size_t, size_t) = 0;
102
  virtual int seek(INT64, int) = 0;
103
  virtual INT64 tell() = 0;
104
  virtual INT64 size() = 0;
105
  virtual int get_char() = 0;
106
  virtual char *gets(char *, int) = 0;
107
  virtual int scanf_one(const char *, void *) = 0;
108
  virtual int eof() = 0;
109
  virtual int jpeg_src(void *);
110
0
  virtual void buffering_off() {}
111
0
  virtual void buffering_on() {}
112
0
  virtual bool is_buffered() { return false; }
113
  /* reimplement in subclass to use parallel access in xtrans_load_raw() if
114
   * OpenMP is not used */
115
1.74k
  virtual int lock() { return 1; } /* success */
116
1.74k
  virtual void unlock() {}
117
1.74k
  virtual const char *fname() { return NULL; };
118
#ifdef LIBRAW_WIN32_UNICODEPATHS
119
  virtual const wchar_t *wfname() { return NULL; };
120
#endif
121
};
122
123
#ifndef LIBRAW_NO_IOSTREAMS_DATASTREAM
124
125
#ifdef LIBRAW_WIN32_DLLDEFS
126
#ifdef LIBRAW_USE_AUTOPTR
127
template class DllDef std::auto_ptr<std::streambuf>;
128
#else
129
template class DllDef std::unique_ptr<std::streambuf>;
130
#endif
131
#endif
132
133
class DllDef LibRaw_file_datastream : public LibRaw_abstract_datastream
134
{
135
protected:
136
#ifdef LIBRAW_USE_AUTOPTR
137
  std::auto_ptr<std::streambuf> f; /* will close() automatically through dtor */
138
#else
139
  std::unique_ptr<std::streambuf> f;
140
#endif
141
  std::string filename;
142
  INT64 _fsize;
143
#ifdef LIBRAW_WIN32_UNICODEPATHS
144
  std::wstring wfilename;
145
#endif
146
147
public:
148
  virtual ~LibRaw_file_datastream();
149
  LibRaw_file_datastream(const char *fname);
150
#ifdef LIBRAW_WIN32_UNICODEPATHS
151
  LibRaw_file_datastream(const wchar_t *fname);
152
#endif
153
  virtual int valid();
154
  virtual int read(void *ptr, size_t size, size_t nmemb);
155
  virtual int eof();
156
  virtual int seek(INT64 o, int whence);
157
  virtual INT64 tell();
158
  virtual INT64 size() { return _fsize; }
159
  virtual int get_char() {return f->sbumpc();}
160
  virtual char *gets(char *str, int sz);
161
  virtual int scanf_one(const char *fmt, void *val);
162
  virtual const char *fname();
163
#ifdef LIBRAW_WIN32_UNICODEPATHS
164
  virtual const wchar_t *wfname();
165
#endif
166
};
167
#endif
168
169
#if defined (LIBRAW_NO_IOSTREAMS_DATASTREAM)  && defined (LIBRAW_WIN32_CALLS)
170
171
struct DllDef LibRaw_bufio_params
172
{
173
    static int bufsize;
174
    static void set_bufsize(int bs);
175
};
176
177
class buffer_t : public std::vector<unsigned char>
178
{
179
public:
180
    INT64 _bstart, _bend;
181
    buffer_t() : std::vector<unsigned char>(LibRaw_bufio_params::bufsize), _bstart(0), _bend(0) {}
182
    int charOReof(INT64 _fpos)
183
    {
184
        if (_bstart < 0LL || _bend < 0LL || _bend < _bstart || _fpos < 0LL)  
185
            return -1;
186
        if ((_bend - _bstart) > (INT64)size()) 
187
            return -1;
188
        if (_fpos >= _bstart && _fpos < _bend)
189
            return data()[_fpos - _bstart];
190
        return -1;
191
    }
192
    bool contains(INT64 _fpos, INT64& contains)
193
    {
194
        if (_bstart < 0LL || _bend < 0LL || _bend < _bstart || _fpos < 0LL)
195
        {
196
            contains = 0;
197
            return false;
198
        }
199
        if ((_bend - _bstart) > (INT64)size())
200
        {
201
          contains = 0;
202
          return false;
203
        }       
204
        if (_fpos >= _bstart && _fpos < _bend)
205
        {
206
            contains = _bend - _fpos;
207
            return true;
208
        }
209
        contains = 0;
210
        return false;
211
    }
212
};
213
214
215
class DllDef LibRaw_bigfile_buffered_datastream : public LibRaw_abstract_datastream
216
{
217
public:
218
    LibRaw_bigfile_buffered_datastream(const char *fname);
219
#ifdef LIBRAW_WIN32_UNICODEPATHS
220
    LibRaw_bigfile_buffered_datastream(const wchar_t *fname);
221
#endif
222
    virtual ~LibRaw_bigfile_buffered_datastream();
223
    virtual int valid();
224
    virtual void buffering_off() { buffered = 0; }
225
  virtual void buffering_on() { buffered = 1; }
226
  virtual bool is_buffered() { return buffered; }
227
    virtual int read(void *ptr, size_t size, size_t nmemb);
228
    virtual int eof();
229
    virtual int seek(INT64 o, int whence);
230
    virtual INT64 tell();
231
    virtual INT64 size() { return _fsize; }
232
    virtual char *gets(char *str, int sz);
233
    virtual int scanf_one(const char *fmt, void *val);
234
    virtual const char *fname();
235
#ifdef LIBRAW_WIN32_UNICODEPATHS
236
    virtual const wchar_t *wfname();
237
#endif
238
    virtual int get_char()
239
    {
240
        int r = iobuffers[0].charOReof(_fpos);
241
        if (r >= 0)
242
        {
243
            _fpos++;
244
            return r;
245
        }
246
        unsigned char c;
247
        r = read(&c, 1, 1);
248
        return r > 0 ? c : r;
249
    }
250
251
protected:
252
    INT64   readAt(void *ptr, size_t size, INT64 off);
253
    bool  fillBufferAt(int buf, INT64 off);
254
    int   selectStringBuffer(INT64 len, INT64& contains);
255
    HANDLE fhandle;
256
    INT64 _fsize;
257
    INT64 _fpos; /* current file position; current buffer start position */
258
#ifdef LIBRAW_WIN32_UNICODEPATHS
259
    std::wstring wfilename;
260
#endif
261
    std::string filename;
262
    buffer_t iobuffers[2];
263
    int buffered;
264
};
265
266
#endif
267
268
class DllDef LibRaw_buffer_datastream : public LibRaw_abstract_datastream
269
{
270
public:
271
  LibRaw_buffer_datastream(const void *buffer, size_t bsize);
272
  virtual ~LibRaw_buffer_datastream();
273
  virtual int valid();
274
  virtual int jpeg_src(void *jpegdata);
275
  virtual int read(void *ptr, size_t sz, size_t nmemb);
276
  virtual int eof();
277
  virtual int seek(INT64 o, int whence);
278
  virtual INT64 tell();
279
0
  virtual INT64 size() { return streamsize; }
280
  virtual char *gets(char *s, int sz);
281
  virtual int scanf_one(const char *fmt, void *val);
282
  virtual int get_char()
283
0
  {
284
0
    if (streampos >= streamsize)   return -1;
285
0
    return buf[streampos++];
286
0
  }
287
288
private:
289
  unsigned char *buf;
290
  size_t streampos, streamsize;
291
};
292
293
class DllDef LibRaw_bigfile_datastream : public LibRaw_abstract_datastream
294
{
295
public:
296
  LibRaw_bigfile_datastream(const char *fname);
297
#ifdef LIBRAW_WIN32_UNICODEPATHS
298
  LibRaw_bigfile_datastream(const wchar_t *fname);
299
#endif
300
  virtual ~LibRaw_bigfile_datastream();
301
  virtual int valid();
302
  virtual int read(void *ptr, size_t size, size_t nmemb);
303
  virtual int eof();
304
  virtual int seek(INT64 o, int whence);
305
  virtual INT64 tell();
306
0
  virtual INT64 size() { return _fsize; }
307
  virtual char *gets(char *str, int sz);
308
  virtual int scanf_one(const char *fmt, void *val);
309
  virtual const char *fname();
310
#ifdef LIBRAW_WIN32_UNICODEPATHS
311
  virtual const wchar_t *wfname();
312
#endif
313
  virtual int get_char()
314
0
  {
315
0
#ifndef LIBRAW_WIN32_CALLS
316
0
    return getc_unlocked(f);
317
#else
318
    return fgetc(f);
319
#endif
320
0
  }
321
322
protected:
323
  FILE *f;
324
  std::string filename;
325
  INT64 _fsize;
326
#ifdef LIBRAW_WIN32_UNICODEPATHS
327
  std::wstring wfilename;
328
#endif
329
};
330
331
#ifdef LIBRAW_WIN32_CALLS
332
class DllDef LibRaw_windows_datastream : public LibRaw_buffer_datastream
333
{
334
public:
335
  /* ctor: high level constructor opens a file by name */
336
  LibRaw_windows_datastream(const TCHAR *sFile);
337
  /* ctor: construct with a file handle - caller is responsible for closing the
338
   * file handle */
339
  LibRaw_windows_datastream(HANDLE hFile);
340
  /* dtor: unmap and close the mapping handle */
341
  virtual ~LibRaw_windows_datastream();
342
  virtual INT64 size() { return cbView_; }
343
344
protected:
345
  void Open(HANDLE hFile);
346
  inline void reconstruct_base()
347
  {
348
    /* this subterfuge is to overcome the private-ness of
349
     * LibRaw_buffer_datastream */
350
    (LibRaw_buffer_datastream &)*this =
351
        LibRaw_buffer_datastream(pView_, (size_t)cbView_);
352
  }
353
354
  HANDLE hMap_;    /* handle of the file mapping */
355
  void *pView_;    /* pointer to the mapped memory */
356
  __int64 cbView_; /* size of the mapping in bytes */
357
};
358
359
#endif
360
361
#ifdef USE_DNGSDK
362
363
class libraw_dng_stream : public dng_stream
364
{
365
public:
366
  libraw_dng_stream(LibRaw_abstract_datastream *p)
367
      : dng_stream((dng_abort_sniffer *)NULL, kBigBufferSize, 0),
368
        parent_stream(p)
369
  {
370
    if (parent_stream)
371
    {
372
    parent_buffered = parent_stream->is_buffered();
373
        parent_stream->buffering_off();
374
    off = parent_stream->tell();
375
    parent_stream->seek(0UL, SEEK_SET); /* seek to start */
376
    }
377
  }
378
  ~libraw_dng_stream()
379
  {
380
    if (parent_stream)
381
    {
382
      if (parent_buffered)
383
        parent_stream->buffering_on();
384
      parent_stream->seek(off, SEEK_SET);
385
    }
386
  }
387
  virtual uint64 DoGetLength()
388
  {
389
    if (parent_stream)
390
      return parent_stream->size();
391
    return 0;
392
  }
393
  virtual void DoRead(void *data, uint32 count, uint64 offset)
394
  {
395
    if (parent_stream)
396
    {
397
      parent_stream->seek(offset, SEEK_SET);
398
      parent_stream->read(data, 1, count);
399
    }
400
  }
401
402
private:
403
  libraw_dng_stream(const libraw_dng_stream &stream);
404
  libraw_dng_stream &operator=(const libraw_dng_stream &stream);
405
  LibRaw_abstract_datastream *parent_stream;
406
  INT64 off;
407
  bool parent_buffered;
408
};
409
410
#endif
411
412
#endif /* cplusplus */
413
414
#endif