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
39class 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
286class 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
513class 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
539extern 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.
545template <typename T>
546class 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
573template <class T>
574bool operator== (const dng_std_allocator<T> &a1,
575				 const dng_std_allocator<T> &a2)
576	{
577	return true;
578	}
579
580template <class T>
581bool 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.
588template <class T> using dng_std_vector = std::vector<T, dng_std_allocator<T> >;
589
590/*****************************************************************************/
591
592#endif
593
594/*****************************************************************************/
595