Leptonica  1.73
Image processing and image analysis suite
utils1.c
Go to the documentation of this file.
1 /*====================================================================*
2  - Copyright (C) 2001 Leptonica. All rights reserved.
3  -
4  - Redistribution and use in source and binary forms, with or without
5  - modification, are permitted provided that the following conditions
6  - are met:
7  - 1. Redistributions of source code must retain the above copyright
8  - notice, this list of conditions and the following disclaimer.
9  - 2. Redistributions in binary form must reproduce the above
10  - copyright notice, this list of conditions and the following
11  - disclaimer in the documentation and/or other materials
12  - provided with the distribution.
13  -
14  - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15  - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16  - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17  - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANY
18  - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  - OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23  - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24  - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  *====================================================================*/
26 
88 #ifdef HAVE_CONFIG_H
89 #include "config_auto.h"
90 #endif /* HAVE_CONFIG_H */
91 
92 #ifdef _WIN32
93 #include <windows.h>
94 #endif /* _WIN32 */
95 
96 //#include <string.h>
97 #include <time.h>
98 #include "allheaders.h"
99 #include <math.h>
100 
101  /* Global for controlling message output at runtime */
102 LEPT_DLL l_int32 LeptMsgSeverity = DEFAULT_SEVERITY;
103 
104 #define DEBUG_SEV 0
105 
106 /*----------------------------------------------------------------------*
107  * Control of error, warning and info messages *
108  *----------------------------------------------------------------------*/
125 l_int32
126 setMsgSeverity(l_int32 newsev)
127 {
128 l_int32 oldsev;
129 char *envsev;
130 
131  PROCNAME("setMsgSeverity");
132 
133  oldsev = LeptMsgSeverity;
134  if (newsev == L_SEVERITY_EXTERNAL) {
135  envsev = getenv("LEPT_MSG_SEVERITY");
136  if (envsev) {
137  LeptMsgSeverity = atoi(envsev);
138 #if DEBUG_SEV
139  L_INFO("message severity set to external\n", procName);
140 #endif /* DEBUG_SEV */
141  } else {
142 #if DEBUG_SEV
143  L_WARNING("environment var LEPT_MSG_SEVERITY not defined\n",
144  procName);
145 #endif /* DEBUG_SEV */
146  }
147  } else {
148  LeptMsgSeverity = newsev;
149 #if DEBUG_SEV
150  L_INFO("message severity set to %d\n", procName, newsev);
151 #endif /* DEBUG_SEV */
152  }
153 
154  return oldsev;
155 }
156 
157 
158 /*----------------------------------------------------------------------*
159  * Error return functions, invoked by macros *
160  * *
161  * (1) These error functions print messages to stderr and allow *
162  * exit from the function that called them. *
163  * (2) They must be invoked only by the macros ERROR_INT, *
164  * ERROR_FLOAT and ERROR_PTR, which are in environ.h *
165  * (3) The print output can be disabled at compile time, either *
166  * by using -DNO_CONSOLE_IO or by setting LeptMsgSeverity. *
167  *----------------------------------------------------------------------*/
176 l_int32
177 returnErrorInt(const char *msg,
178  const char *procname,
179  l_int32 ival)
180 {
181  fprintf(stderr, "Error in %s: %s\n", procname, msg);
182  return ival;
183 }
184 
185 
194 l_float32
195 returnErrorFloat(const char *msg,
196  const char *procname,
197  l_float32 fval)
198 {
199  fprintf(stderr, "Error in %s: %s\n", procname, msg);
200  return fval;
201 }
202 
203 
212 void *
213 returnErrorPtr(const char *msg,
214  const char *procname,
215  void *pval)
216 {
217  fprintf(stderr, "Error in %s: %s\n", procname, msg);
218  return pval;
219 }
220 
221 
222 /*--------------------------------------------------------------------*
223  * Test files for equivalence *
224  *--------------------------------------------------------------------*/
233 l_int32
234 filesAreIdentical(const char *fname1,
235  const char *fname2,
236  l_int32 *psame)
237 {
238 l_int32 i, same;
239 size_t nbytes1, nbytes2;
240 l_uint8 *array1, *array2;
241 
242  PROCNAME("filesAreIdentical");
243 
244  if (!psame)
245  return ERROR_INT("&same not defined", procName, 1);
246  *psame = 0;
247  if (!fname1 || !fname2)
248  return ERROR_INT("both names not defined", procName, 1);
249 
250  nbytes1 = nbytesInFile(fname1);
251  nbytes2 = nbytesInFile(fname2);
252  if (nbytes1 != nbytes2)
253  return 0;
254 
255  if ((array1 = l_binaryRead(fname1, &nbytes1)) == NULL)
256  return ERROR_INT("array1 not read", procName, 1);
257  if ((array2 = l_binaryRead(fname2, &nbytes2)) == NULL) {
258  LEPT_FREE(array1);
259  return ERROR_INT("array2 not read", procName, 1);
260  }
261  same = 1;
262  for (i = 0; i < nbytes1; i++) {
263  if (array1[i] != array2[i]) {
264  same = 0;
265  break;
266  }
267  }
268  LEPT_FREE(array1);
269  LEPT_FREE(array2);
270  *psame = same;
271 
272  return 0;
273 }
274 
275 
276 /*--------------------------------------------------------------------------*
277  * 16 and 32 bit byte-swapping on big endian and little endian machines *
278  * *
279  * These are typically used for I/O conversions: *
280  * (1) endian conversion for data that was read from a file *
281  * (2) endian conversion on data before it is written to a file *
282  *--------------------------------------------------------------------------*/
283 
284 /*--------------------------------------------------------------------*
285  * 16-bit byte swapping *
286  *--------------------------------------------------------------------*/
287 #ifdef L_BIG_ENDIAN
288 
289 l_uint16
290 convertOnBigEnd16(l_uint16 shortin)
291 {
292  return ((shortin << 8) | (shortin >> 8));
293 }
294 
295 l_uint16
296 convertOnLittleEnd16(l_uint16 shortin)
297 {
298  return shortin;
299 }
300 
301 #else /* L_LITTLE_ENDIAN */
302 
303 l_uint16
304 convertOnLittleEnd16(l_uint16 shortin)
305 {
306  return ((shortin << 8) | (shortin >> 8));
307 }
308 
309 l_uint16
310 convertOnBigEnd16(l_uint16 shortin)
311 {
312  return shortin;
313 }
314 
315 #endif /* L_BIG_ENDIAN */
316 
317 
318 /*--------------------------------------------------------------------*
319  * 32-bit byte swapping *
320  *--------------------------------------------------------------------*/
321 #ifdef L_BIG_ENDIAN
322 
323 l_uint32
324 convertOnBigEnd32(l_uint32 wordin)
325 {
326  return ((wordin << 24) | ((wordin << 8) & 0x00ff0000) |
327  ((wordin >> 8) & 0x0000ff00) | (wordin >> 24));
328 }
329 
330 l_uint32
331 convertOnLittleEnd32(l_uint32 wordin)
332 {
333  return wordin;
334 }
335 
336 #else /* L_LITTLE_ENDIAN */
337 
338 l_uint32
339 convertOnLittleEnd32(l_uint32 wordin)
340 {
341  return ((wordin << 24) | ((wordin << 8) & 0x00ff0000) |
342  ((wordin >> 8) & 0x0000ff00) | (wordin >> 24));
343 }
344 
345 l_uint32
346 convertOnBigEnd32(l_uint32 wordin)
347 {
348  return wordin;
349 }
350 
351 #endif /* L_BIG_ENDIAN */
352 
353 
354 /*---------------------------------------------------------------------*
355  * File corruption operations *
356  *---------------------------------------------------------------------*/
377 l_int32
378 fileCorruptByDeletion(const char *filein,
379  l_float32 loc,
380  l_float32 size,
381  const char *fileout)
382 {
383 l_int32 i, locb, sizeb, rembytes;
384 size_t inbytes, outbytes;
385 l_uint8 *datain, *dataout;
386 
387  PROCNAME("fileCorruptByDeletion");
388 
389  if (!filein || !fileout)
390  return ERROR_INT("filein and fileout not both specified", procName, 1);
391  if (loc < 0.0 || loc >= 1.0)
392  return ERROR_INT("loc must be in [0.0 ... 1.0)", procName, 1);
393  if (size <= 0.0)
394  return ERROR_INT("size must be > 0.0", procName, 1);
395  if (loc + size > 1.0)
396  size = 1.0 - loc;
397 
398  datain = l_binaryRead(filein, &inbytes);
399  locb = (l_int32)(loc * inbytes + 0.5);
400  locb = L_MIN(locb, inbytes - 1);
401  sizeb = (l_int32)(size * inbytes + 0.5);
402  sizeb = L_MAX(1, sizeb);
403  sizeb = L_MIN(sizeb, inbytes - locb); /* >= 1 */
404  L_INFO("Removed %d bytes at location %d\n", procName, sizeb, locb);
405  rembytes = inbytes - locb - sizeb; /* >= 0; to be copied, after excision */
406 
407  outbytes = inbytes - sizeb;
408  dataout = (l_uint8 *)LEPT_CALLOC(outbytes, 1);
409  for (i = 0; i < locb; i++)
410  dataout[i] = datain[i];
411  for (i = 0; i < rembytes; i++)
412  dataout[locb + i] = datain[locb + sizeb + i];
413  l_binaryWrite(fileout, "w", dataout, outbytes);
414 
415  LEPT_FREE(datain);
416  LEPT_FREE(dataout);
417  return 0;
418 }
419 
420 
441 l_int32
442 fileCorruptByMutation(const char *filein,
443  l_float32 loc,
444  l_float32 size,
445  const char *fileout)
446 {
447 l_int32 i, locb, sizeb;
448 size_t bytes;
449 l_uint8 *data;
450 
451  PROCNAME("fileCorruptByMutation");
452 
453  if (!filein || !fileout)
454  return ERROR_INT("filein and fileout not both specified", procName, 1);
455  if (loc < 0.0 || loc >= 1.0)
456  return ERROR_INT("loc must be in [0.0 ... 1.0)", procName, 1);
457  if (size <= 0.0)
458  return ERROR_INT("size must be > 0.0", procName, 1);
459  if (loc + size > 1.0)
460  size = 1.0 - loc;
461 
462  data = l_binaryRead(filein, &bytes);
463  locb = (l_int32)(loc * bytes + 0.5);
464  locb = L_MIN(locb, bytes - 1);
465  sizeb = (l_int32)(size * bytes + 0.5);
466  sizeb = L_MAX(1, sizeb);
467  sizeb = L_MIN(sizeb, bytes - locb); /* >= 1 */
468  L_INFO("Randomizing %d bytes at location %d\n", procName, sizeb, locb);
469 
470  /* Make an array of random bytes and do the substitution */
471  for (i = 0; i < sizeb; i++) {
472  data[locb + i] =
473  (l_uint8)(255.9 * ((l_float64)rand() / (l_float64)RAND_MAX));
474  }
475 
476  l_binaryWrite(fileout, "w", data, bytes);
477  LEPT_FREE(data);
478  return 0;
479 }
480 
481 
482 /*---------------------------------------------------------------------*
483  * Generate random integer in given range *
484  *---------------------------------------------------------------------*/
499 l_int32
501  l_int32 seed,
502  l_int32 *pval)
503 {
504  PROCNAME("genRandomIntegerInRange");
505 
506  if (!pval)
507  return ERROR_INT("&val not defined", procName, 1);
508  *pval = 0;
509  if (range < 2)
510  return ERROR_INT("range must be >= 2", procName, 1);
511 
512  if (seed > 0) srand(seed);
513  *pval = (l_int32)((l_float64)range *
514  ((l_float64)rand() / (l_float64)RAND_MAX));
515  return 0;
516 }
517 
518 
519 /*---------------------------------------------------------------------*
520  * Simple math function *
521  *---------------------------------------------------------------------*/
536 l_int32
537 lept_roundftoi(l_float32 fval)
538 {
539  return (fval >= 0.0) ? (l_int32)(fval + 0.5) : (l_int32)(fval - 0.5);
540 }
541 
542 
543 /*---------------------------------------------------------------------*
544  * 64-bit hash functions *
545  *---------------------------------------------------------------------*/
568 l_int32
569 l_hashStringToUint64(const char *str,
570  l_uint64 *phash)
571 {
572 l_uint64 hash, mulp;
573 
574  PROCNAME("l_hashStringToUint64");
575 
576  if (phash) *phash = 0;
577  if (!str || (str[0] == '\0'))
578  return ERROR_INT("str not defined or empty", procName, 1);
579  if (!phash)
580  return ERROR_INT("&hash not defined", procName, 1);
581 
582  mulp = 26544357894361247; /* prime, about 1/700 of the max uint64 */
583  hash = 104395301;
584  while (*str) {
585  hash += (*str++ * mulp) ^ (hash >> 7); /* shift [1...23] are ok */
586  }
587  *phash = hash ^ (hash << 37);
588  return 0;
589 }
590 
591 
614 l_int32
616  l_int32 y,
617  l_uint64 *phash)
618 {
619  PROCNAME("l_hashPtToUint64");
620 
621  if (!phash)
622  return ERROR_INT("&hash not defined", procName, 1);
623 
624  *phash = (l_uint64)(2173249142.3849 * x + 3763193258.6227 * y);
625  return 0;
626 }
627 
628 
654 l_int32
655 l_hashFloat64ToUint64(l_int32 nbuckets,
656  l_float64 val,
657  l_uint64 *phash)
658 {
659  PROCNAME("l_hashFloatToUint64");
660 
661  if (!phash)
662  return ERROR_INT("&hash not defined", procName, 1);
663  *phash = (l_uint64)((21.732491 * nbuckets) * val);
664  return 0;
665 }
666 
667 
668 /*---------------------------------------------------------------------*
669  * Prime finders *
670  *---------------------------------------------------------------------*/
678 l_int32
679 findNextLargerPrime(l_int32 start,
680  l_uint32 *pprime)
681 {
682 l_int32 i, is_prime;
683 
684  PROCNAME("findNextLargerPrime");
685 
686  if (!pprime)
687  return ERROR_INT("&prime not defined", procName, 1);
688  *pprime = 0;
689  if (start <= 0)
690  return ERROR_INT("start must be > 0", procName, 1);
691 
692  for (i = start + 1; ; i++) {
693  lept_isPrime(i, &is_prime, NULL);
694  if (is_prime) {
695  *pprime = i;
696  return 0;
697  }
698  }
699 
700  return ERROR_INT("prime not found!", procName, 1);
701 }
702 
703 
713 l_int32
714 lept_isPrime(l_uint64 n,
715  l_int32 *pis_prime,
716  l_uint32 *pfactor)
717 {
718 l_uint32 div;
719 l_uint64 limit, ratio;
720 
721  PROCNAME("lept_isPrime");
722 
723  if (pis_prime) *pis_prime = 0;
724  if (pfactor) *pfactor = 0;
725  if (!pis_prime)
726  return ERROR_INT("&is_prime not defined", procName, 1);
727  if (n <= 0)
728  return ERROR_INT("n must be > 0", procName, 1);
729 
730  if (n % 2 == 0) {
731  if (pfactor) *pfactor = 2;
732  return 0;
733  }
734 
735  limit = (l_uint64)sqrt((l_float64)n);
736  for (div = 3; div < limit; div += 2) {
737  ratio = n / div;
738  if (ratio * div == n) {
739  if (pfactor) *pfactor = div;
740  return 0;
741  }
742  }
743 
744  *pis_prime = 1;
745  return 0;
746 }
747 
748 
749 /*---------------------------------------------------------------------*
750  * Gray code conversion *
751  *---------------------------------------------------------------------*/
764 l_uint32
766 {
767  return (val >> 1) ^ val;
768 }
769 
770 
777 l_uint32
779 {
780 l_uint32 shift;
781 
782  for (shift = 1; shift < 32; shift <<= 1)
783  val ^= val >> shift;
784  return val;
785 }
786 
787 
788 /*---------------------------------------------------------------------*
789  * Leptonica version number *
790  *---------------------------------------------------------------------*/
799 char *
801 {
802 size_t bufsize = 100;
803 
804  char *version = (char *)LEPT_CALLOC(bufsize, sizeof(char));
805 
806 #ifdef _MSC_VER
807  #ifdef _USRDLL
808  char dllStr[] = "DLL";
809  #else
810  char dllStr[] = "LIB";
811  #endif
812  #ifdef _DEBUG
813  char debugStr[] = "Debug";
814  #else
815  char debugStr[] = "Release";
816  #endif
817  #ifdef _M_IX86
818  char bitStr[] = " x86";
819  #elif _M_X64
820  char bitStr[] = " x64";
821  #else
822  char bitStr[] = "";
823  #endif
824  snprintf(version, bufsize, "leptonica-%d.%d.%d (%s, %s) [MSC v.%d %s %s%s]",
825  LIBLEPT_MAJOR_VERSION, LIBLEPT_MINOR_VERSION, LIBLEPT_PATCH_VERSION,
826  __DATE__, __TIME__, _MSC_VER, dllStr, debugStr, bitStr);
827 
828 #else
829 
830  snprintf(version, bufsize, "leptonica-%d.%d.%d", LIBLEPT_MAJOR_VERSION,
831  LIBLEPT_MINOR_VERSION, LIBLEPT_PATCH_VERSION);
832 
833 #endif /* _MSC_VER */
834  return version;
835 }
836 
837 
838 /*---------------------------------------------------------------------*
839  * Timing procs *
840  *---------------------------------------------------------------------*/
841 #ifndef _WIN32
842 
843 #include <sys/time.h>
844 #include <sys/resource.h>
845 
846 static struct rusage rusage_before;
847 static struct rusage rusage_after;
848 
858 void
860 {
861  getrusage(RUSAGE_SELF, &rusage_before);
862 }
863 
864 l_float32
865 stopTimer(void)
866 {
867 l_int32 tsec, tusec;
868 
869  getrusage(RUSAGE_SELF, &rusage_after);
870 
871  tsec = rusage_after.ru_utime.tv_sec - rusage_before.ru_utime.tv_sec;
872  tusec = rusage_after.ru_utime.tv_usec - rusage_before.ru_utime.tv_usec;
873  return (tsec + ((l_float32)tusec) / 1000000.0);
874 }
875 
876 
890 L_TIMER
892 {
893 struct rusage *rusage_start;
894 
895  rusage_start = (struct rusage *)LEPT_CALLOC(1, sizeof(struct rusage));
896  getrusage(RUSAGE_SELF, rusage_start);
897  return rusage_start;
898 }
899 
900 l_float32
901 stopTimerNested(L_TIMER rusage_start)
902 {
903 l_int32 tsec, tusec;
904 struct rusage rusage_stop;
905 
906  getrusage(RUSAGE_SELF, &rusage_stop);
907 
908  tsec = rusage_stop.ru_utime.tv_sec -
909  ((struct rusage *)rusage_start)->ru_utime.tv_sec;
910  tusec = rusage_stop.ru_utime.tv_usec -
911  ((struct rusage *)rusage_start)->ru_utime.tv_usec;
912  LEPT_FREE(rusage_start);
913  return (tsec + ((l_float32)tusec) / 1000000.0);
914 }
915 
916 
924 void
925 l_getCurrentTime(l_int32 *sec,
926  l_int32 *usec)
927 {
928 struct timeval tv;
929 
930  gettimeofday(&tv, NULL);
931  if (sec) *sec = (l_int32)tv.tv_sec;
932  if (usec) *usec = (l_int32)tv.tv_usec;
933  return;
934 }
935 
936 
937 #else /* _WIN32 : resource.h not implemented under Windows */
938 
939  /* Note: if division by 10^7 seems strange, the time is expressed
940  * as the number of 100-nanosecond intervals that have elapsed
941  * since 12:00 A.M. January 1, 1601. */
942 
943 static ULARGE_INTEGER utime_before;
944 static ULARGE_INTEGER utime_after;
945 
946 void
947 startTimer(void)
948 {
949 HANDLE this_process;
950 FILETIME start, stop, kernel, user;
951 
952  this_process = GetCurrentProcess();
953 
954  GetProcessTimes(this_process, &start, &stop, &kernel, &user);
955 
956  utime_before.LowPart = user.dwLowDateTime;
957  utime_before.HighPart = user.dwHighDateTime;
958 }
959 
960 l_float32
961 stopTimer(void)
962 {
963 HANDLE this_process;
964 FILETIME start, stop, kernel, user;
965 ULONGLONG hnsec; /* in units of hecto-nanosecond (100 ns) intervals */
966 
967  this_process = GetCurrentProcess();
968 
969  GetProcessTimes(this_process, &start, &stop, &kernel, &user);
970 
971  utime_after.LowPart = user.dwLowDateTime;
972  utime_after.HighPart = user.dwHighDateTime;
973  hnsec = utime_after.QuadPart - utime_before.QuadPart;
974  return (l_float32)(signed)hnsec / 10000000.0;
975 }
976 
977 L_TIMER
978 startTimerNested(void)
979 {
980 HANDLE this_process;
981 FILETIME start, stop, kernel, user;
982 ULARGE_INTEGER *utime_start;
983 
984  this_process = GetCurrentProcess();
985 
986  GetProcessTimes (this_process, &start, &stop, &kernel, &user);
987 
988  utime_start = (ULARGE_INTEGER *)LEPT_CALLOC(1, sizeof(ULARGE_INTEGER));
989  utime_start->LowPart = user.dwLowDateTime;
990  utime_start->HighPart = user.dwHighDateTime;
991  return utime_start;
992 }
993 
994 l_float32
995 stopTimerNested(L_TIMER utime_start)
996 {
997 HANDLE this_process;
998 FILETIME start, stop, kernel, user;
999 ULARGE_INTEGER utime_stop;
1000 ULONGLONG hnsec; /* in units of 100 ns intervals */
1001 
1002  this_process = GetCurrentProcess ();
1003 
1004  GetProcessTimes (this_process, &start, &stop, &kernel, &user);
1005 
1006  utime_stop.LowPart = user.dwLowDateTime;
1007  utime_stop.HighPart = user.dwHighDateTime;
1008  hnsec = utime_stop.QuadPart - ((ULARGE_INTEGER *)utime_start)->QuadPart;
1009  LEPT_FREE(utime_start);
1010  return (l_float32)(signed)hnsec / 10000000.0;
1011 }
1012 
1013 void
1014 l_getCurrentTime(l_int32 *sec,
1015  l_int32 *usec)
1016 {
1017 ULARGE_INTEGER utime, birthunix;
1018 FILETIME systemtime;
1019 LONGLONG birthunixhnsec = 116444736000000000; /*in units of 100 ns */
1020 LONGLONG usecs;
1021 
1022  GetSystemTimeAsFileTime(&systemtime);
1023  utime.LowPart = systemtime.dwLowDateTime;
1024  utime.HighPart = systemtime.dwHighDateTime;
1025 
1026  birthunix.LowPart = (DWORD) birthunixhnsec;
1027  birthunix.HighPart = birthunixhnsec >> 32;
1028 
1029  usecs = (LONGLONG) ((utime.QuadPart - birthunix.QuadPart) / 10);
1030 
1031  if (sec) *sec = (l_int32) (usecs / 1000000);
1032  if (usec) *usec = (l_int32) (usecs % 1000000);
1033  return;
1034 }
1035 
1036 #endif
1037 
1038 
1053 L_WALLTIMER *
1055 {
1056 L_WALLTIMER *timer;
1057 
1058  timer = (L_WALLTIMER *)LEPT_CALLOC(1, sizeof(L_WALLTIMER));
1059  l_getCurrentTime(&timer->start_sec, &timer->start_usec);
1060  return timer;
1061 }
1062 
1069 l_float32
1071 {
1072 l_int32 tsec, tusec;
1073 L_WALLTIMER *timer;
1074 
1075  PROCNAME("stopWallTimer");
1076 
1077  if (!ptimer)
1078  return (l_float32)ERROR_FLOAT("&timer not defined", procName, 0.0);
1079  timer = *ptimer;
1080  if (!timer)
1081  return (l_float32)ERROR_FLOAT("timer not defined", procName, 0.0);
1082 
1083  l_getCurrentTime(&timer->stop_sec, &timer->stop_usec);
1084  tsec = timer->stop_sec - timer->start_sec;
1085  tusec = timer->stop_usec - timer->start_usec;
1086  LEPT_FREE(timer);
1087  *ptimer = NULL;
1088  return (tsec + ((l_float32)tusec) / 1000000.0);
1089 }
1090 
1091 
1104 char *
1106 {
1107 char buf[sizeof "199812231952SS-08'00'"] = "", sep = 'Z';
1108 l_int32 gmt_offset, relh, relm;
1109 time_t ut, lt;
1110 struct tm *tptr;
1111 
1112  ut = time(NULL);
1113 
1114  /* This generates a second "time_t" value by calling "gmtime" to
1115  fill in a "tm" structure expressed as UTC and then calling
1116  "mktime", which expects a "tm" structure expressed as the
1117  local time. The result is a value that is offset from the
1118  value returned by the "time" function by the local UTC offset.
1119  "tm_isdst" is set to -1 to tell "mktime" to determine for
1120  itself whether DST is in effect. This is necessary because
1121  "gmtime" always sets "tm_isdst" to 0, which would tell
1122  "mktime" to presume that DST is not in effect. */
1123  tptr = gmtime(&ut);
1124  tptr->tm_isdst = -1;
1125  lt = mktime(tptr);
1126 
1127  /* Calls "difftime" to obtain the resulting difference in seconds,
1128  * because "time_t" is an opaque type, per the C standard. */
1129  gmt_offset = (l_int32) difftime(ut, lt);
1130 
1131  if (gmt_offset > 0)
1132  sep = '+';
1133  else if (gmt_offset < 0)
1134  sep = '-';
1135 
1136  relh = L_ABS(gmt_offset) / 3600;
1137  relm = (L_ABS(gmt_offset) % 3600) / 60;
1138 
1139  strftime(buf, sizeof(buf), "%Y%m%d%H%M%S", localtime(&ut));
1140  sprintf(buf + 14, "%c%02d'%02d'", sep, relh, relm);
1141  return stringNew(buf);
1142 }
size_t nbytesInFile(const char *filename)
nbytesInFile()
Definition: utils2.c:1409
LEPT_DLL l_int32 LeptMsgSeverity
Definition: utils1.c:102
l_uint32 convertBinaryToGrayCode(l_uint32 val)
convertBinaryToGrayCode()
Definition: utils1.c:765
L_TIMER startTimerNested(void)
startTimerNested(), stopTimerNested()
Definition: utils1.c:891
l_int32 l_hashFloat64ToUint64(l_int32 nbuckets, l_float64 val, l_uint64 *phash)
l_hashFloat64ToUint64()
Definition: utils1.c:655
l_int32 lept_roundftoi(l_float32 fval)
lept_roundftoi()
Definition: utils1.c:537
l_int32 setMsgSeverity(l_int32 newsev)
setMsgSeverity()
Definition: utils1.c:126
void startTimer(void)
startTimer(), stopTimer()
Definition: utils1.c:859
char * stringNew(const char *src)
stringNew()
Definition: utils2.c:202
l_float32 stopWallTimer(L_WALLTIMER **ptimer)
stopWallTimer()
Definition: utils1.c:1070
void * returnErrorPtr(const char *msg, const char *procname, void *pval)
returnErrorPtr()
Definition: utils1.c:213
l_int32 fileCorruptByDeletion(const char *filein, l_float32 loc, l_float32 size, const char *fileout)
fileCorruptByDeletion()
Definition: utils1.c:378
l_int32 filesAreIdentical(const char *fname1, const char *fname2, l_int32 *psame)
filesAreIdentical()
Definition: utils1.c:234
l_int32 l_hashPtToUint64(l_int32 x, l_int32 y, l_uint64 *phash)
l_hashPtToUint64()
Definition: utils1.c:615
l_int32 fileCorruptByMutation(const char *filein, l_float32 loc, l_float32 size, const char *fileout)
fileCorruptByMutation()
Definition: utils1.c:442
l_uint8 * l_binaryRead(const char *filename, size_t *pnbytes)
l_binaryRead()
Definition: utils2.c:1154
l_int32 findNextLargerPrime(l_int32 start, l_uint32 *pprime)
findNextLargerPrime()
Definition: utils1.c:679
char * getLeptonicaVersion()
getLeptonicaVersion()
Definition: utils1.c:800
l_int32 l_hashStringToUint64(const char *str, l_uint64 *phash)
l_hashStringToUint64()
Definition: utils1.c:569
l_float32 returnErrorFloat(const char *msg, const char *procname, l_float32 fval)
returnErrorFloat()
Definition: utils1.c:195
l_int32 lept_isPrime(l_uint64 n, l_int32 *pis_prime, l_uint32 *pfactor)
lept_isPrime()
Definition: utils1.c:714
void l_getCurrentTime(l_int32 *sec, l_int32 *usec)
l_getCurrentTime()
Definition: utils1.c:925
L_WALLTIMER * startWallTimer(void)
startWallTimer()
Definition: utils1.c:1054
l_int32 l_binaryWrite(const char *filename, const char *operation, void *data, size_t nbytes)
l_binaryWrite()
Definition: utils2.c:1367
l_int32 genRandomIntegerInRange(l_int32 range, l_int32 seed, l_int32 *pval)
genRandomIntegerInRange()
Definition: utils1.c:500
char * l_getFormattedDate()
l_getFormattedDate()
Definition: utils1.c:1105
l_uint32 convertGrayCodeToBinary(l_uint32 val)
convertGrayCodeToBinary()
Definition: utils1.c:778
l_int32 returnErrorInt(const char *msg, const char *procname, l_int32 ival)
returnErrorInt()
Definition: utils1.c:177