Home | History | Annotate | Download | only in source
      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