1 /*****************************************************************************/ 2 // Copyright 2006-2007 Adobe Systems Incorporated 3 // All Rights Reserved. 4 // 5 // NOTICE: Adobe permits you to use, modify, and distribute this file in 6 // accordance with the terms of the Adobe license agreement accompanying it. 7 /*****************************************************************************/ 8 9 /* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_memory.h#1 $ */ 10 /* $DateTime: 2012/05/30 13:28:51 $ */ 11 /* $Change: 832332 $ */ 12 /* $Author: tknoll $ */ 13 14 /** Support for memory allocation. 15 */ 16 17 /*****************************************************************************/ 18 19 #ifndef __dng_memory__ 20 #define __dng_memory__ 21 22 /*****************************************************************************/ 23 24 #include "dng_classes.h" 25 #include "dng_exceptions.h" 26 #include "dng_safe_arithmetic.h" 27 #include "dng_types.h" 28 29 #include <cstdlib> 30 #include <vector> 31 32 /*****************************************************************************/ 33 34 /// \brief Class to provide resource acquisition is instantiation discipline 35 /// for small memory allocations. 36 /// 37 /// This class does not use dng_memory_allocator for memory allocation. 38 39 class dng_memory_data 40 { 41 42 private: 43 44 char *fBuffer; 45 46 public: 47 48 /// Construct an empty memory buffer using malloc. 49 /// \exception dng_memory_full with fErrorCode equal to dng_error_memory. 50 51 dng_memory_data (); 52 53 /// Construct memory buffer of size bytes using malloc. 54 /// \param size Number of bytes of memory needed. 55 /// \exception dng_memory_full with fErrorCode equal to dng_error_memory. 56 57 dng_memory_data (uint32 size); 58 59 /// Note: This constructor is for internal use only and should not be 60 /// considered part of the DNG SDK API. 61 /// 62 /// Construct memory buffer of count elements of elementSize bytes each. 63 /// \param count Number of elements. 64 /// \param elementSize Size of each element. 65 /// \exception dng_memory_full with fErrorCode equal to dng_error_memory. 66 dng_memory_data (uint32 count, std::size_t elementSize); 67 68 /// Release memory buffer using free. 69 70 ~dng_memory_data (); 71 72 /// Clear existing memory buffer and allocate new memory of size bytes. 73 /// \param size Number of bytes of memory needed. 74 /// \exception dng_memory_full with fErrorCode equal to dng_error_memory. 75 76 void Allocate (uint32 size); 77 78 /// Note: This method is for internal use only and should not be 79 /// considered part of the DNG SDK API. 80 /// 81 /// Clear existing memory buffer and allocate new memory of count 82 /// elements of elementSize bytes each. 83 /// \param count Number of elements. 84 /// \param elementSize Size of each element. 85 /// \exception dng_memory_full with fErrorCode equal to dng_error_memory. 86 void Allocate (uint32 count, std::size_t elementSize); 87 88 /// Release any allocated memory using free. Object is still valid and 89 /// Allocate can be called again. 90 91 void Clear (); 92 93 /// Return pointer to allocated memory as a void *.. 94 /// \retval void * valid for as many bytes as were allocated. 95 96 void * Buffer () 97 { 98 return fBuffer; 99 } 100 101 /// Return pointer to allocated memory as a const void *. 102 /// \retval const void * valid for as many bytes as were allocated. 103 104 const void * Buffer () const 105 { 106 return fBuffer; 107 } 108 109 /// Return pointer to allocated memory as a char *. 110 /// \retval char * valid for as many bytes as were allocated. 111 112 char * Buffer_char () 113 { 114 return (char *) Buffer (); 115 } 116 117 /// Return pointer to allocated memory as a const char *. 118 /// \retval const char * valid for as many bytes as were allocated. 119 120 const char * Buffer_char () const 121 { 122 return (const char *) Buffer (); 123 } 124 125 /// Return pointer to allocated memory as a uint8 *. 126 /// \retval uint8 * valid for as many bytes as were allocated. 127 128 uint8 * Buffer_uint8 () 129 { 130 return (uint8 *) Buffer (); 131 } 132 133 /// Return pointer to allocated memory as a const uint8 *. 134 /// \retval const uint8 * valid for as many bytes as were allocated. 135 136 const uint8 * Buffer_uint8 () const 137 { 138 return (const uint8 *) Buffer (); 139 } 140 141 /// Return pointer to allocated memory as a uint16 *. 142 /// \retval uint16 * valid for as many bytes as were allocated. 143 144 uint16 * Buffer_uint16 () 145 { 146 return (uint16 *) Buffer (); 147 } 148 149 /// Return pointer to allocated memory as a const uint16 *. 150 /// \retval const uint16 * valid for as many bytes as were allocated. 151 152 const uint16 * Buffer_uint16 () const 153 { 154 return (const uint16 *) Buffer (); 155 } 156 157 /// Return pointer to allocated memory as a int16 *. 158 /// \retval int16 * valid for as many bytes as were allocated. 159 160 int16 * Buffer_int16 () 161 { 162 return (int16 *) Buffer (); 163 } 164 165 /// Return pointer to allocated memory as a const int16 *. 166 /// \retval const int16 * valid for as many bytes as were allocated. 167 168 const int16 * Buffer_int16 () const 169 { 170 return (const int16 *) Buffer (); 171 } 172 173 /// Return pointer to allocated memory as a uint32 *. 174 /// \retval uint32 * valid for as many bytes as were allocated. 175 176 uint32 * Buffer_uint32 () 177 { 178 return (uint32 *) Buffer (); 179 } 180 181 /// Return pointer to allocated memory as a uint32 *. 182 /// \retval uint32 * valid for as many bytes as were allocated. 183 184 const uint32 * Buffer_uint32 () const 185 { 186 return (const uint32 *) Buffer (); 187 } 188 189 /// Return pointer to allocated memory as a const int32 *. 190 /// \retval const int32 * valid for as many bytes as were allocated. 191 192 int32 * Buffer_int32 () 193 { 194 return (int32 *) Buffer (); 195 } 196 197 /// Return pointer to allocated memory as a const int32 *. 198 /// \retval const int32 * valid for as many bytes as were allocated. 199 200 const int32 * Buffer_int32 () const 201 { 202 return (const int32 *) Buffer (); 203 } 204 205 /// Return pointer to allocated memory as a uint64 *. 206 /// \retval uint64 * valid for as many bytes as were allocated. 207 208 uint64 * Buffer_uint64 () 209 { 210 return (uint64 *) Buffer (); 211 } 212 213 /// Return pointer to allocated memory as a uint64 *. 214 /// \retval uint64 * valid for as many bytes as were allocated. 215 216 const uint64 * Buffer_uint64 () const 217 { 218 return (const uint64 *) Buffer (); 219 } 220 221 /// Return pointer to allocated memory as a const int64 *. 222 /// \retval const int64 * valid for as many bytes as were allocated. 223 224 int64 * Buffer_int64 () 225 { 226 return (int64 *) Buffer (); 227 } 228 229 /// Return pointer to allocated memory as a const int64 *. 230 /// \retval const int64 * valid for as many bytes as were allocated. 231 232 const int64 * Buffer_int64 () const 233 { 234 return (const int64 *) Buffer (); 235 } 236 237 /// Return pointer to allocated memory as a real32 *. 238 /// \retval real32 * valid for as many bytes as were allocated. 239 240 real32 * Buffer_real32 () 241 { 242 return (real32 *) Buffer (); 243 } 244 245 /// Return pointer to allocated memory as a const real32 *. 246 /// \retval const real32 * valid for as many bytes as were allocated. 247 248 const real32 * Buffer_real32 () const 249 { 250 return (const real32 *) Buffer (); 251 } 252 253 /// Return pointer to allocated memory as a real64 *. 254 /// \retval real64 * valid for as many bytes as were allocated. 255 256 real64 * Buffer_real64 () 257 { 258 return (real64 *) Buffer (); 259 } 260 261 /// Return pointer to allocated memory as a const real64 *. 262 /// \retval const real64 * valid for as many bytes as were allocated. 263 264 const real64 * Buffer_real64 () const 265 { 266 return (const real64 *) Buffer (); 267 } 268 269 private: 270 271 // Hidden copy constructor and assignment operator. 272 273 dng_memory_data (const dng_memory_data &data); 274 275 dng_memory_data & operator= (const dng_memory_data &data); 276 277 }; 278 279 /*****************************************************************************/ 280 281 /// \brief Class to provide resource acquisition is instantiation discipline for 282 /// image buffers and other larger memory allocations. 283 /// 284 /// This class requires a dng_memory_allocator for allocation. 285 286 class dng_memory_block 287 { 288 289 private: 290 291 uint32 fLogicalSize; 292 293 char *fBuffer; 294 295 protected: 296 297 dng_memory_block (uint32 logicalSize) 298 : fLogicalSize (logicalSize) 299 , fBuffer (NULL) 300 { 301 } 302 303 uint32 PhysicalSize () 304 { 305 306 // This size is padded for TWO reasons! The first is allow alignment 307 // to 16-byte boundaries if the allocator does not do that already. The 308 // second, which is very important, so to provide safe overread areas for 309 // SSE2-type bottlenecks, which can often be written faster by allowing them 310 // to reading slightly block. Someone on the image core them did not 311 // understand this and removed this padding. I'm undoing this removal 312 // and restoring this padding, since removing it might lead to memory 313 // access crashes in some cases. 314 315 // This padding is throwing off all of our allocations (f.e. dng_string, pixel buffers, etc) 316 // that uses dng_memory_block on iOS/Android that is memory limited. Imagecore carefully 317 // allocates pow2 tile buffers, but this bumps us to the next ssd block (+4K). 318 // This also makes it difficult to identify memory reports in Instruments since all 319 // numbers are off by 64. Imagecore never crashed from the removal of the padding. 320 // The allocator on Win64/Mac64 is 16-byte aligned already. iOS is too. 321 // Linux is 8 byte, but it's using mem_align. 322 // We should fix the SIMD routines and revisit removing this padding - Alec. 323 324 uint32 result; 325 if (!SafeUint32Add(fLogicalSize, 64u, &result)) 326 { 327 ThrowMemoryFull("Arithmetic overflow in PhysicalSize()"); 328 } 329 330 return result; 331 332 } 333 334 void SetBuffer (void *p) 335 { 336 fBuffer = (char *) ((((uintptr) p) + 15) & ~((uintptr) 15)); 337 } 338 339 public: 340 341 virtual ~dng_memory_block () 342 { 343 } 344 345 dng_memory_block * Clone (dng_memory_allocator &allocator) const; 346 347 /// Getter for available size, in bytes, of memory block. 348 /// \retval size in bytes of available memory in memory block. 349 350 uint32 LogicalSize () const 351 { 352 return fLogicalSize; 353 } 354 355 /// Return pointer to allocated memory as a void *.. 356 /// \retval void * valid for as many bytes as were allocated. 357 358 void * Buffer () 359 { 360 return fBuffer; 361 } 362 363 /// Return pointer to allocated memory as a const void *. 364 /// \retval const void * valid for as many bytes as were allocated. 365 366 const void * Buffer () const 367 { 368 return fBuffer; 369 } 370 371 /// Return pointer to allocated memory as a char *. 372 /// \retval char * valid for as many bytes as were allocated. 373 374 char * Buffer_char () 375 { 376 return (char *) Buffer (); 377 } 378 379 /// Return pointer to allocated memory as a const char *. 380 /// \retval const char * valid for as many bytes as were allocated. 381 382 const char * Buffer_char () const 383 { 384 return (const char *) Buffer (); 385 } 386 387 /// Return pointer to allocated memory as a uint8 *. 388 /// \retval uint8 * valid for as many bytes as were allocated. 389 390 uint8 * Buffer_uint8 () 391 { 392 return (uint8 *) Buffer (); 393 } 394 395 /// Return pointer to allocated memory as a const uint8 *. 396 /// \retval const uint8 * valid for as many bytes as were allocated. 397 398 const uint8 * Buffer_uint8 () const 399 { 400 return (const uint8 *) Buffer (); 401 } 402 403 /// Return pointer to allocated memory as a uint16 *. 404 /// \retval uint16 * valid for as many bytes as were allocated. 405 406 uint16 * Buffer_uint16 () 407 { 408 return (uint16 *) Buffer (); 409 } 410 411 /// Return pointer to allocated memory as a const uint16 *. 412 /// \retval const uint16 * valid for as many bytes as were allocated. 413 414 const uint16 * Buffer_uint16 () const 415 { 416 return (const uint16 *) Buffer (); 417 } 418 419 /// Return pointer to allocated memory as a int16 *. 420 /// \retval int16 * valid for as many bytes as were allocated. 421 422 int16 * Buffer_int16 () 423 { 424 return (int16 *) Buffer (); 425 } 426 427 /// Return pointer to allocated memory as a const int16 *. 428 /// \retval const int16 * valid for as many bytes as were allocated. 429 430 const int16 * Buffer_int16 () const 431 { 432 return (const int16 *) Buffer (); 433 } 434 435 /// Return pointer to allocated memory as a uint32 *. 436 /// \retval uint32 * valid for as many bytes as were allocated. 437 438 uint32 * Buffer_uint32 () 439 { 440 return (uint32 *) Buffer (); 441 } 442 443 /// Return pointer to allocated memory as a const uint32 *. 444 /// \retval const uint32 * valid for as many bytes as were allocated. 445 446 const uint32 * Buffer_uint32 () const 447 { 448 return (const uint32 *) Buffer (); 449 } 450 451 /// Return pointer to allocated memory as a int32 *. 452 /// \retval int32 * valid for as many bytes as were allocated. 453 454 int32 * Buffer_int32 () 455 { 456 return (int32 *) Buffer (); 457 } 458 459 /// Return pointer to allocated memory as a const int32 *. 460 /// \retval const int32 * valid for as many bytes as were allocated. 461 462 const int32 * Buffer_int32 () const 463 { 464 return (const int32 *) Buffer (); 465 } 466 467 /// Return pointer to allocated memory as a real32 *. 468 /// \retval real32 * valid for as many bytes as were allocated. 469 470 real32 * Buffer_real32 () 471 { 472 return (real32 *) Buffer (); 473 } 474 475 /// Return pointer to allocated memory as a const real32 *. 476 /// \retval const real32 * valid for as many bytes as were allocated. 477 478 const real32 * Buffer_real32 () const 479 { 480 return (const real32 *) Buffer (); 481 } 482 483 /// Return pointer to allocated memory as a real64 *. 484 /// \retval real64 * valid for as many bytes as were allocated. 485 486 real64 * Buffer_real64 () 487 { 488 return (real64 *) Buffer (); 489 } 490 491 /// Return pointer to allocated memory as a const real64 *. 492 /// \retval const real64 * valid for as many bytes as were allocated. 493 494 const real64 * Buffer_real64 () const 495 { 496 return (const real64 *) Buffer (); 497 } 498 499 private: 500 501 // Hidden copy constructor and assignment operator. 502 503 dng_memory_block (const dng_memory_block &data); 504 505 dng_memory_block & operator= (const dng_memory_block &data); 506 507 }; 508 509 /*****************************************************************************/ 510 511 /// \brief Interface for dng_memory_block allocator. 512 513 class dng_memory_allocator 514 { 515 516 public: 517 518 virtual ~dng_memory_allocator () 519 { 520 } 521 522 /// Allocate a dng_memory block. 523 /// \param size Number of bytes in memory block. 524 /// \retval A dng_memory_block with at least size bytes of valid storage. 525 /// \exception dng_exception with fErrorCode equal to dng_error_memory. 526 527 virtual dng_memory_block * Allocate (uint32 size); 528 529 }; 530 531 /*****************************************************************************/ 532 533 /// \brief Default memory allocator used if NULL is passed in for allocator 534 /// when constructing a dng_host. 535 /// 536 /// Uses new and delete for memory block object and malloc/free for underlying 537 /// buffer. 538 539 extern dng_memory_allocator gDefaultDNGMemoryAllocator; 540 541 /*****************************************************************************/ 542 543 // C++ allocator (i.e. an implementation of the Allocator concept) that throws a 544 // dng_exception with error code dng_error_memory if it cannot allocate memory. 545 template <typename T> 546 class dng_std_allocator 547 { 548 549 public: 550 typedef T value_type; 551 552 // Default implementations of default constructor and copy constructor. 553 dng_std_allocator () = default; 554 dng_std_allocator (const dng_std_allocator&) = default; 555 template<typename U> dng_std_allocator (const dng_std_allocator<U>&) {} 556 557 T* allocate (size_t n) 558 { 559 const size_t size = SafeSizetMult(n, sizeof (T)); 560 T *retval = static_cast<T *> (malloc (size)); 561 if (!retval) { 562 ThrowMemoryFull (); 563 } 564 return retval; 565 } 566 567 void deallocate (T *ptr, size_t n) 568 { 569 free (ptr); 570 } 571 }; 572 573 template <class T> 574 bool operator== (const dng_std_allocator<T> &a1, 575 const dng_std_allocator<T> &a2) 576 { 577 return true; 578 } 579 580 template <class T> 581 bool operator!= (const dng_std_allocator<T> &a1, 582 const dng_std_allocator<T> &a2) 583 { 584 return false; 585 } 586 587 // std::vector specialized to use dng_std_allocator for allocation. 588 template <class T> using dng_std_vector = std::vector<T, dng_std_allocator<T> >; 589 590 /*****************************************************************************/ 591 592 #endif 593 594 /*****************************************************************************/ 595