1 : /******************************************************************************
2 : *
3 : * Purpose: Various private (undocumented) utility functions.
4 : *
5 : ******************************************************************************
6 : * Copyright (c) 2009
7 : * PCI Geomatics, 50 West Wilmot Street, Richmond Hill, Ont, Canada
8 : *
9 : * Permission is hereby granted, free of charge, to any person obtaining a
10 : * copy of this software and associated documentation files (the "Software"),
11 : * to deal in the Software without restriction, including without limitation
12 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 : * and/or sell copies of the Software, and to permit persons to whom the
14 : * Software is furnished to do so, subject to the following conditions:
15 : *
16 : * The above copyright notice and this permission notice shall be included
17 : * in all copies or substantial portions of the Software.
18 : *
19 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 : * DEALINGS IN THE SOFTWARE.
26 : ****************************************************************************/
27 : #include "pcidsk_config.h"
28 : #include "pcidsk_types.h"
29 : #include "pcidsk_exception.h"
30 : #include "core/pcidsk_utils.h"
31 : #include <cstdlib>
32 : #include <cstring>
33 : #include <cctype>
34 :
35 : using namespace PCIDSK;
36 :
37 : /************************************************************************/
38 : /* GetCurrentDateTime() */
39 : /************************************************************************/
40 :
41 : // format we want: "HH:MM DDMMMYYYY \0"
42 :
43 : #include <time.h>
44 : #include <sys/types.h>
45 :
46 106 : void PCIDSK::GetCurrentDateTime( char *out_time )
47 :
48 : {
49 : time_t clock;
50 : char ctime_out[25];
51 :
52 106 : time( &clock );
53 106 : strncpy( ctime_out, ctime(&clock), 24 ); // TODO: reentrance issue?
54 :
55 : // ctime() products: "Wed Jun 30 21:49:08 1993\n"
56 :
57 106 : ctime_out[24] = '\0';
58 :
59 106 : out_time[0] = ctime_out[11];
60 106 : out_time[1] = ctime_out[12];
61 106 : out_time[2] = ':';
62 106 : out_time[3] = ctime_out[14];
63 106 : out_time[4] = ctime_out[15];
64 106 : out_time[5] = ' ';
65 106 : out_time[6] = ctime_out[8];
66 106 : out_time[7] = ctime_out[9];
67 106 : out_time[8] = ctime_out[4];
68 106 : out_time[9] = ctime_out[5];
69 106 : out_time[10] = ctime_out[6];
70 106 : out_time[11] = ctime_out[20];
71 106 : out_time[12] = ctime_out[21];
72 106 : out_time[13] = ctime_out[22];
73 106 : out_time[14] = ctime_out[23];
74 106 : out_time[15] = ' ';
75 106 : out_time[16] = '\0';
76 106 : }
77 :
78 : /************************************************************************/
79 : /* UCaseStr() */
80 : /* */
81 : /* Force a string into upper case "in place". */
82 : /************************************************************************/
83 :
84 44 : std::string &PCIDSK::UCaseStr( std::string &target )
85 :
86 : {
87 220 : for( unsigned int i = 0; i < target.size(); i++ )
88 : {
89 176 : if( islower(target[i]) )
90 0 : target[i] = toupper(target[i]);
91 : }
92 :
93 44 : return target;
94 : }
95 :
96 : /************************************************************************/
97 : /* atouint64() */
98 : /************************************************************************/
99 :
100 824 : uint64 PCIDSK::atouint64( const char *str_value )
101 :
102 : {
103 : #if defined(__MSVCRT__) || defined(_MSC_VER)
104 : return (uint64) _atoi64( str_value );
105 : #else
106 824 : return (uint64) atoll( str_value );
107 : #endif
108 : }
109 :
110 : /************************************************************************/
111 : /* atoint64() */
112 : /************************************************************************/
113 :
114 0 : int64 PCIDSK::atoint64( const char *str_value )
115 :
116 : {
117 : #if defined(__MSVCRT__) || defined(_MSC_VER)
118 : return (int64) _atoi64( str_value );
119 : #else
120 0 : return (int64) atoll( str_value );
121 : #endif
122 : }
123 :
124 : /************************************************************************/
125 : /* SwapPixels() */
126 : /************************************************************************/
127 : /**
128 : * @brief Perform an endianess swap for a given buffer of pixels
129 : *
130 : * Baed on the provided data type, do an appropriate endianess swap for
131 : * a buffer of pixels. Deals with the Complex case specially, in
132 : * particular.
133 : *
134 : * @param data the pixels to be swapped
135 : * @param type the data type of the pixels
136 : * @param count the count of pixels (not bytes, words, etc.)
137 : */
138 : void PCIDSK::SwapPixels(void* const data,
139 : const eChanType type,
140 280 : const std::size_t count)
141 : {
142 280 : switch(type) {
143 : case CHN_8U:
144 : case CHN_16U:
145 : case CHN_16S:
146 : case CHN_32R:
147 240 : SwapData(data, DataTypeSize(type), count);
148 240 : break;
149 : case CHN_C16U:
150 : case CHN_C16S:
151 : case CHN_C32R:
152 40 : SwapData(data, DataTypeSize(type) / 2, count * 2);
153 40 : break;
154 : default:
155 : ThrowPCIDSKException("Unknown data type passed to SwapPixels."
156 0 : "This is a software bug. Please contact your vendor.");
157 : }
158 280 : }
159 :
160 : /************************************************************************/
161 : /* SwapData() */
162 : /************************************************************************/
163 :
164 280 : void PCIDSK::SwapData( void* const data, const int size, const int wcount )
165 :
166 : {
167 280 : uint8* data8 = reinterpret_cast<uint8*>(data);
168 280 : std::size_t count = wcount;
169 :
170 280 : if( size == 2 )
171 : {
172 : uint8 t;
173 :
174 4640 : for( ; count; count-- )
175 : {
176 4400 : t = data8[0];
177 4400 : data8[0] = data8[1];
178 4400 : data8[1] = t;
179 :
180 4400 : data8 += 2;
181 : }
182 : }
183 40 : else if( size == 1 )
184 : /* do nothing */;
185 40 : else if( size == 4 )
186 : {
187 : uint8 t;
188 :
189 640 : for( ; count; count-- )
190 : {
191 600 : t = data8[0];
192 600 : data8[0] = data8[3];
193 600 : data8[3] = t;
194 :
195 600 : t = data8[1];
196 600 : data8[1] = data8[2];
197 600 : data8[2] = t;
198 :
199 600 : data8 += 4;
200 : }
201 : }
202 0 : else if( size == 8 )
203 : {
204 : uint8 t;
205 :
206 0 : for( ; count; count-- )
207 : {
208 0 : t = data8[0];
209 0 : data8[0] = data8[7];
210 0 : data8[7] = t;
211 :
212 0 : t = data8[1];
213 0 : data8[1] = data8[6];
214 0 : data8[6] = t;
215 :
216 0 : t = data8[2];
217 0 : data8[2] = data8[5];
218 0 : data8[5] = t;
219 :
220 0 : t = data8[3];
221 0 : data8[3] = data8[4];
222 0 : data8[4] = t;
223 :
224 0 : data8 += 8;
225 : }
226 : }
227 : else
228 0 : ThrowPCIDSKException( "Unsupported data size in SwapData()" );
229 280 : }
230 :
231 : /************************************************************************/
232 : /* BigEndianSystem() */
233 : /************************************************************************/
234 :
235 0 : bool PCIDSK::BigEndianSystem()
236 :
237 : {
238 0 : unsigned short test_value = 1;
239 : char test_char_value[2];
240 :
241 0 : memcpy( test_char_value, &test_value, 2 );
242 :
243 0 : return test_char_value[0] == 0;
244 : }
245 :
246 :
247 : /************************************************************************/
248 : /* ParseTileFormat() */
249 : /* */
250 : /* Parse blocksize and compression out of a TILED interleaving */
251 : /* string as passed to the Create() function or stored in */
252 : /* _DBLayout metadata. */
253 : /************************************************************************/
254 :
255 : void PCIDSK::ParseTileFormat( std::string full_text,
256 0 : int &block_size, std::string &compression )
257 :
258 : {
259 0 : compression = "NONE";
260 0 : block_size = 127;
261 :
262 0 : UCaseStr( full_text );
263 :
264 : /* -------------------------------------------------------------------- */
265 : /* Only operate on tiled stuff. */
266 : /* -------------------------------------------------------------------- */
267 0 : if( strncmp(full_text.c_str(),"TILED",5) != 0 )
268 0 : return;
269 :
270 : /* -------------------------------------------------------------------- */
271 : /* Do we have a block size? */
272 : /* -------------------------------------------------------------------- */
273 0 : const char *next_text = full_text.c_str() + 5;
274 :
275 0 : if( isdigit(*next_text) )
276 : {
277 0 : block_size = atoi(next_text);
278 0 : while( isdigit(*next_text) )
279 0 : next_text++;
280 : }
281 :
282 0 : while( *next_text == ' ' )
283 0 : next_text++;
284 :
285 : /* -------------------------------------------------------------------- */
286 : /* Do we have a compression type? */
287 : /* -------------------------------------------------------------------- */
288 0 : if( *next_text != '\0' )
289 : {
290 0 : compression = next_text;
291 0 : if (compression == "NO_WARNINGS")
292 0 : compression = "";
293 0 : else if( compression != "RLE"
294 : && strncmp(compression.c_str(),"JPEG",4) != 0
295 : && compression != "NONE"
296 : && compression != "QUADTREE" )
297 : {
298 : ThrowPCIDSKException( "Unsupported tile compression scheme '%s' requested.",
299 0 : compression.c_str() );
300 : }
301 : }
302 : }
303 :
304 : /************************************************************************/
305 : /* pci_strcasecmp() */
306 : /************************************************************************/
307 :
308 0 : int PCIDSK::pci_strcasecmp( const char *string1, const char *string2 )
309 :
310 : {
311 : int i;
312 :
313 0 : for( i = 0; string1[i] != '\0' && string2[i] != '\0'; i++ )
314 : {
315 0 : char c1 = string1[i];
316 0 : char c2 = string2[i];
317 :
318 0 : if( islower(c1) )
319 0 : c1 = toupper(c1);
320 0 : if( islower(c2) )
321 0 : c2 = toupper(c2);
322 :
323 0 : if( c1 < c2 )
324 0 : return -1;
325 0 : else if( c1 > c2 )
326 0 : return 1;
327 : else
328 0 : return 0;
329 : }
330 :
331 0 : if( string1[i] == '\0' && string2[i] == '\0' )
332 0 : return 0;
333 0 : else if( string1[i] == '\0' )
334 0 : return 1;
335 : else
336 0 : return -1;
337 : }
338 :
339 : /************************************************************************/
340 : /* pci_strncasecmp() */
341 : /************************************************************************/
342 :
343 1969 : int PCIDSK::pci_strncasecmp( const char *string1, const char *string2, int len )
344 :
345 : {
346 : int i;
347 :
348 3745 : for( i = 0; i < len; i++ )
349 : {
350 3276 : if( string1[i] == '\0' && string2[i] == '\0' )
351 0 : return 0;
352 3276 : else if( string1[i] == '\0' )
353 0 : return 1;
354 3276 : else if( string2[i] == '\0' )
355 0 : return -1;
356 :
357 3276 : char c1 = string1[i];
358 3276 : char c2 = string2[i];
359 :
360 3276 : if( islower(c1) )
361 0 : c1 = toupper(c1);
362 3276 : if( islower(c2) )
363 0 : c2 = toupper(c2);
364 :
365 3276 : if( c1 < c2 )
366 910 : return -1;
367 2366 : else if( c1 > c2 )
368 590 : return 1;
369 : }
370 :
371 469 : return 0;
372 : }
373 :
|