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 
Buffer()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 
Buffer()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 
Buffer_char()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 
Buffer_char()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 
Buffer_uint8()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 
Buffer_uint8()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 
Buffer_uint16()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 
Buffer_uint16()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 
Buffer_int16()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 
Buffer_int16()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 
Buffer_uint32()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 
Buffer_uint32()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 
Buffer_int32()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 
Buffer_int32()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 
Buffer_uint64()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 
Buffer_uint64()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 
Buffer_int64()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 
Buffer_int64()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 
Buffer_real32()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 
Buffer_real32()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 
Buffer_real64()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 
Buffer_real64()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 
dng_memory_block(uint32 logicalSize)297 		dng_memory_block (uint32 logicalSize)
298 			:	fLogicalSize (logicalSize)
299 			,	fBuffer (NULL)
300 			{
301 			}
302 
PhysicalSize()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 
SetBuffer(void * p)334 		void SetBuffer (void *p)
335 			{
336 			fBuffer = (char *) ((((uintptr) p) + 15) & ~((uintptr) 15));
337 			}
338 
339 	public:
340 
~dng_memory_block()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 
LogicalSize()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 
Buffer()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 
Buffer()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 
Buffer_char()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 
Buffer_char()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 
Buffer_uint8()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 
Buffer_uint8()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 
Buffer_uint16()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 
Buffer_uint16()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 
Buffer_int16()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 
Buffer_int16()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 
Buffer_uint32()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 
Buffer_uint32()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 
Buffer_int32()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 
Buffer_int32()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 
Buffer_real32()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 
Buffer_real32()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 
Buffer_real64()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 
Buffer_real64()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 
~dng_memory_allocator()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;
dng_std_allocator(const dng_std_allocator<U> &)555 		template<typename U> dng_std_allocator (const dng_std_allocator<U>&) {}
556 
allocate(size_t n)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 
deallocate(T * ptr,size_t n)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