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