1 /*******************************************************************************
2 **
3 ** Photivo
4 **
5 ** Copyright (C) 2008,2009 Jos De Laender <jos.de_laender@telenet.be>
6 ** Copyright (C) 2009,2010 Michael Munzert <mail@mm-log.com>
7 ** Copyright (C) 2015 Bernd Schoeler <brjohn@brother-john.net>
8 **
9 ** This file is part of Photivo.
10 **
11 ** Photivo is free software: you can redistribute it and/or modify
12 ** it under the terms of the GNU General Public License version 3
13 ** as published by the Free Software Foundation.
14 **
15 ** Photivo is distributed in the hope that it will be useful,
16 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ** GNU General Public License for more details.
19 **
20 ** You should have received a copy of the GNU General Public License
21 ** along with Photivo.  If not, see <http://www.gnu.org/licenses/>.
22 **
23 *******************************************************************************/
24 
25 #ifndef DLDEFINES_H
26 #define DLDEFINES_H
27 
28 #include <array>
29 #include <memory>
30 #include <vector>
31 
32 // pulls in INT32_MAX etc.
33 #define __STDC_LIMIT_MACROS
34 #include <cstdint>
35 
36 #include <cstdlib>
37 
38 // disable the file manager
39 // #define PT_WITHOUT_FILEMGR
40 
41 //==============================================================================
42 
43 template<class T>
DelAndNull(T * & p)44 inline void DelAndNull(T*& p) {
45   delete p;
46   p = nullptr;
47 }
48 
49 //==============================================================================
50 // Calculate the square
51 template <typename T>
ptSqr(const T & a)52 inline T ptSqr(const T& a) { return a*a; }
53 
54 //==============================================================================
55 
56 // Custom unique ptr creation. Because there is no std::make_unique().
57 template<typename T, typename ...Args>
make_unique(Args &&...args)58 std::unique_ptr<T> make_unique(Args&& ...args) {
59   return std::unique_ptr<T>(new T(std::forward<Args>(args)... ));
60 }
61 
62 // -----------------------------------------------------------------------------
63 
64 // c_unique_ptr: A unique_ptr for C-style malloc/free resources.
65 namespace pt {
66   namespace detail {
67     struct c_deleter {
operatorc_deleter68       void operator()(void* ptr) { free(ptr); }
69     };
70   }
71   template<typename T>
72   using c_unique_ptr = std::unique_ptr<T, detail::c_deleter>;
73 }
74 
75 // -----------------------------------------------------------------------------
76 /*!
77  * TMatrix ist a 2-dimensional std::array with the same declaration syntax as a
78  * C-style array, i.e. first dimension for rows, second dimension for columns.
79  */
80 template <typename T, size_t rows, size_t columns>
81 using TMatrix = std::array<std::array<T, columns>, rows>;
82 
83 namespace pt {
84   /*!
85    * A template to deep copy a two-dimensional C-style array to a TMatrix. Note that you
86    * must specifiy the template parameters excplicitely, i.e. call this functions like this:
87    * int int_array[23][42] {};
88    * auto matrix = arrayToMatrix<int, 23, 42>(int_array);
89    */
90   template<typename T, size_t rows, size_t columns>
arrayToMatrix(T array[rows][columns])91   TMatrix<T, rows, columns> arrayToMatrix(T array[rows][columns]) {
92     TMatrix<T, rows, columns> result;
93     memcpy(result.data(), array, rows*columns);
94     return result;
95   }
96 }
97 
98 // -----------------------------------------------------------------------------
99 
100 typedef std::array<uint16_t, 3> TPixel16;
101 typedef std::array<uint8_t,  4> TPixel8;
102 typedef std::vector<TPixel16>   TImage16Data;
103 typedef std::vector<TPixel8>    TImage8Data;
104 typedef std::vector<uint8_t>    TImage8RawData;
105 using TChannelMatrix = TMatrix<float,3,3>;
106 
107 //==============================================================================
108 // Some macro's (most cannot go efficiently in functions).
109 
110 #ifndef SQR
111   #define SQR(x) ((x)*(x))
112 #endif
113 #undef  ABS
114 #undef  MIN
115 #undef  MAX
116 #define ABS(x) (((int)(x) ^ ((int)(x) >> 31)) - ((int)(x) >> 31))
117 #define SWAP(a,b) { a=a+b; b=a-b; a=a-b; }
118 #define SIGN(x) ((x) == 0 ? 0 : ((x) < 0 ? -1 : 1 ))
119 #define STRINGIFY(x) #x
120 #define TOSTRING(x) STRINGIFY(x)
121 #define AT __PRETTY_FUNCTION__
122 //":" __FILE__ ":" TOSTRING(__LINE__)
123 #define CRLF "\r\n"
124 
125 // Thanks QT
126 template <typename T>
ptMin(const T & a,const T & b)127 inline const T &ptMin(const T &a, const T &b) { if (a < b) return a; return b; }
128 template <typename T>
ptMax(const T & a,const T & b)129 inline const T &ptMax(const T &a, const T &b) { if (a < b) return b; return a; }
130 template <typename T>
ptBound(const T & min,const T & val,const T & max)131 inline const T &ptBound(const T &min, const T &val, const T &max)
132 { return ptMax(min, ptMin(max, val)); }
133 
134 #define MIN(a, b)         ptMin(a, b)
135 #define MAX(a, b)         ptMax(a, b)
136 #define LIM(x, min, max)  ptBound(min, x, max)
137 #define ULIM(x, y, z)     ((y) < (z) ? LIM(x,y,z) : LIM(x,z,y))
138 #define CLIP(x)           ptBound(0, x, 0xffff)
139 
140 ////////////////////////////////////////////////////////////////////////////////
141 //
142 // Following 'functions' are macro implemented for :
143 //   - configurability to get them out and in.
144 //   - to get always a correct reference to the line number where inserted.
145 //
146 ////////////////////////////////////////////////////////////////////////////////
147 
148 // Uncomment me for malloc/calloc/free related leaks.
149 // #define DEBUG_MEMORY
150 
151 #ifdef DEBUG_MEMORY
152 
153   #include "ptCalloc.h"
154 
155   #define CALLOC(Num,Size)  ptCalloc(Num,Size,__FILE__,__LINE__,this)
156   #define CALLOC2(Num,Size) ptCalloc(Num,Size,__FILE__,__LINE__,NULL)
157   #define MALLOC(Size)      ptCalloc(1,Size,__FILE__,__LINE__,this)
158   #define MALLOC2(Size)     ptCalloc(1,Size,__FILE__,__LINE__,NULL)
159   #define FREE(x)           {ptFree(x,__FILE__,__LINE__,this); x=NULL;}
160   #define FREE2(x)          {ptFree(x,__FILE__,__LINE__,NULL); x=NULL;}
161   #define ALLOCATED(x)      ptAllocated(x,__FILE__,__LINE__)
162 
163 #else
164 
165   #define CALLOC(Num,Size)  ptCalloc_Ex(Num,Size)
166   #define CALLOC2(Num,Size) ptCalloc_Ex(Num,Size)
167   #define MALLOC(Size) malloc(Size)
168   #define MALLOC2(Size) malloc(Size)
169   // Remark free(NULL) is valid nop !
170   #define FREE(x) {free(x); x=NULL; }
171   #define FREE2(x) {free(x); x=NULL; }
172   #define ALLOCATED(x) ;
173 
174 #endif
175 
176 // Close a file descriptor and put it on NULL
177 
178 #define FCLOSE(x) {                                                \
179   if (x) fclose(x);                                                \
180   x=NULL;                                                          \
181 };
182 
183 // A function to trace key values in the program (debug of course)
184 
185 #define ENABLE_TRACE
186 #ifdef ENABLE_TRACE
187 #define TRACEKEYVALS(x,y,z) {                                      \
188   printf("(%-25s,%5d): ",__FILE__,__LINE__);                       \
189   printf("%-20s: ",x);                                              \
190   printf(y,z);                                                     \
191   printf("\n");                                                    \
192   fflush(stdout);                                                  \
193 }
194 #else
195 #define TRACEKEYVALS(x,y,z) ;
196 #endif
197 
198 // TRACEMAIN does something comparably , but basically gives
199 // only progress info on the graphical pipe.
200 
201 #define ENABLE_TRACEMAIN
202 #ifdef ENABLE_TRACEMAIN
203 #define TRACEMAIN(x,y) {                                           \
204   printf("(%-25s,%5d): ",__FILE__,__LINE__);                       \
205   printf(x,y);                                                     \
206   printf("\n");                                                    \
207   fflush(stdout);                                                  \
208 }
209 #else
210 #define TRACEMAIN(x,y) ;
211 #endif
212 
213 // Debug function can be used to drop quick and dirty an image.
214 // w,h are the dimensions. b is the buffer of the image.
215 // depth is 3 or 4 (according to buffer layout).
216 
217 #define DROP_IMAGE(w,h,b,depth) {                                  \
218   char FileName[100];                                              \
219   sprintf(FileName,"%s_%d.imagedrop",__FILE__,__LINE__);           \
220   FILE *DropFile = fopen(FileName,"wb");                           \
221   if (!DropFile) exit(EXIT_FAILURE);                               \
222   if (fwrite(b,2*depth,w*h,DropFile) != w*h) exit(EXIT_FAILURE);   \
223   fclose(DropFile);                                                \
224 }
225 
226 #endif
227 
228 ////////////////////////////////////////////////////////////////////////////////
229