env_stdio_interface.c

Go to the documentation of this file.
00001 /*!@file Envision/env_stdio_interface.c */
00002 
00003 // //////////////////////////////////////////////////////////////////// //
00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005   //
00005 // by the University of Southern California (USC) and the iLab at USC.  //
00006 // See http://iLab.usc.edu for information about this project.          //
00007 // //////////////////////////////////////////////////////////////////// //
00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00010 // in Visual Environments, and Applications'' by Christof Koch and      //
00011 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00012 // pending; application number 09/912,225 filed July 23, 2001; see      //
00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00014 // //////////////////////////////////////////////////////////////////// //
00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00016 //                                                                      //
00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00018 // redistribute it and/or modify it under the terms of the GNU General  //
00019 // Public License as published by the Free Software Foundation; either  //
00020 // version 2 of the License, or (at your option) any later version.     //
00021 //                                                                      //
00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00025 // PURPOSE.  See the GNU General Public License for more details.       //
00026 //                                                                      //
00027 // You should have received a copy of the GNU General Public License    //
00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00030 // Boston, MA 02111-1307 USA.                                           //
00031 // //////////////////////////////////////////////////////////////////// //
00032 //
00033 // Primary maintainer for this file: Rob Peters <rjpeters at usc dot edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Envision/env_stdio_interface.c $
00035 // $Id: env_stdio_interface.c 12962 2010-03-06 02:13:53Z irock $
00036 //
00037 
00038 #ifndef ENVISION_ENV_STDIO_INTERFACE_C_DEFINED
00039 #define ENVISION_ENV_STDIO_INTERFACE_C_DEFINED
00040 
00041 #include "Envision/env_stdio_interface.h"
00042 
00043 #include "Envision/env_alloc.h"
00044 #include "Envision/env_image.h"
00045 #include "Envision/env_log.h"
00046 
00047 #include <ctype.h>
00048 #include <errno.h>
00049 #include <stdarg.h>
00050 #include <stdio.h> // for fprintf()
00051 #include <stdlib.h> // for abort()
00052 #include <string.h> // for strerror()
00053 
00054 // ######################################################################
00055 static void lfatal(const char *msg, ...)
00056         __attribute__((format(__printf__,1,2)));
00057 
00058 static void lfatal(const char *msg, ...)
00059 {
00060         va_list args;
00061         va_start(args, msg);
00062 
00063         vfprintf(stderr, msg, args);
00064 
00065         va_end(args);
00066 
00067         fprintf(stderr, "\n");
00068         fflush(stderr);
00069 
00070         abort();
00071 }
00072 
00073 // ######################################################################
00074 static void div2(const env_size_t numer, const env_size_t denom,
00075                  const env_size_t ndigits,
00076                  env_size_t* const whole, env_size_t* const fract)
00077 {
00078   *whole = numer / denom;
00079   *fract = 0;
00080   env_size_t rem = numer - (*whole * denom);
00081   for (env_size_t i = 0; i < ndigits; ++i)
00082     {
00083       rem *= 10;
00084       const env_size_t newwhole = rem / denom;
00085       ENV_ASSERT(newwhole < 10);
00086       rem = rem - (newwhole * denom);
00087       *fract *= 10;
00088       *fract += newwhole;
00089     }
00090 }
00091 
00092 // ######################################################################
00093 void env_stdio_assert_handler(const char* what, int custom_msg,
00094                                      const char* where, int line_no)
00095 {
00096         if (custom_msg)
00097                 fprintf(stderr, "Assertion failed (%s:%d):\n\t%s\n\n",
00098                         where, line_no, what);
00099         else
00100                 fprintf(stderr, "Assertion failed (%s:%d):\n\texpected '%s'\n\n",
00101                         where, line_no, what);
00102         abort();
00103 }
00104 
00105 // ######################################################################
00106 void env_stdio_print_alloc_stats(const struct env_alloc_stats* p,
00107                                  const env_size_t block_size)
00108 {
00109         env_size_t kiB_block_size_whole, kiB_block_size_fract;
00110         div2(block_size, 1024, 2,
00111              &kiB_block_size_whole, &kiB_block_size_fract);
00112 
00113         ENV_ASSERT(block_size > 0);
00114 
00115         env_size_t n_cache_blocks = 0;
00116 
00117         for (env_size_t i = 0; i < p->ncache_used; ++i)
00118         {
00119                 const env_size_t nb =
00120                         (p->cache[i].num_allocations
00121                          * p->cache[i].alloc_size);
00122 
00123                 n_cache_blocks += p->cache[i].num_allocations;
00124 
00125                 env_size_t kiB_alloc_whole, kiB_alloc_fract;
00126                 div2(nb, 1024, 2,
00127                      &kiB_alloc_whole, &kiB_alloc_fract);
00128 
00129                 env_size_t kiB_alloc_size_whole, kiB_alloc_size_fract;
00130                 div2(p->cache[i].alloc_size, 1024, 4,
00131                      &kiB_alloc_size_whole, &kiB_alloc_size_fract);
00132 
00133                 env_size_t alloc_percent_whole, alloc_percent_fract;
00134                 div2(nb*100, p->bytes_allocated, 2,
00135                      &alloc_percent_whole, &alloc_percent_fract);
00136 
00137                 env_size_t block_ratio_whole, block_ratio_fract;
00138                 char symbol;
00139 
00140                 if (p->cache[i].alloc_size - p->overhead >= block_size
00141                     || p->cache[i].alloc_size - p->overhead <= 1)
00142                 {
00143                         div2(p->cache[i].alloc_size - p->overhead,
00144                              block_size, 1,
00145                              &block_ratio_whole, &block_ratio_fract);
00146                         symbol = '*';
00147                 }
00148                 else
00149                 {
00150                         div2(block_size,
00151                              p->cache[i].alloc_size - p->overhead, 1,
00152                              &block_ratio_whole, &block_ratio_fract);
00153                         symbol = '/';
00154                 }
00155 
00156                 fprintf(stderr,
00157                         "memstats: cache[%02lu/%02lu]: "
00158                         "%5lu.%02lukiB (%3lu.%02lu%%) "
00159                         "in %4lu allocations "
00160                         "(%2lu active) of %5lu.%04lukiB"
00161                         " (%lu.%02lukiB %c %5lu.%01lu + %2luB)\n",
00162                         i, ENV_NCACHE,
00163                         kiB_alloc_whole, kiB_alloc_fract,
00164                         alloc_percent_whole, alloc_percent_fract,
00165                         p->cache[i].num_allocations,
00166                         p->cache[i].num_active,
00167                         kiB_alloc_size_whole, kiB_alloc_size_fract,
00168                         kiB_block_size_whole, kiB_block_size_fract,
00169                         (int) symbol,
00170                         block_ratio_whole, block_ratio_fract,
00171                         p->overhead);
00172         }
00173 
00174         env_size_t kiB_alloc_whole, kiB_alloc_fract;
00175         div2(p->bytes_allocated, 1024, 2,
00176              &kiB_alloc_whole, &kiB_alloc_fract);
00177 
00178         env_size_t n_blocks_whole, n_blocks_fract;
00179         div2(p->bytes_allocated, block_size, 1,
00180              &n_blocks_whole, &n_blocks_fract);
00181 
00182         fprintf(stderr,
00183                 "memstats: =====[TOTAL]: "
00184                 "%5lu.%02lukiB (100.00%%) "
00185                 "in %4lu allocations "
00186                 "(%2lu active) ================"
00187                 " (%lu.%02lukiB * %5lu.%01lu      )\n",
00188                 kiB_alloc_whole, kiB_alloc_fract,
00189                 n_cache_blocks,
00190                 p->nallocations_current,
00191                 kiB_block_size_whole, kiB_block_size_fract,
00192                 n_blocks_whole, n_blocks_fract);
00193 
00194         fprintf(stderr,
00195                 "memstats: %lu/%lu cache table entries in use\n",
00196                 p->ncache_used, ENV_NCACHE);
00197 
00198         fprintf(stderr,
00199                 "memstats: block alignment: %lu bytes\n", p->nalign);
00200 
00201         fprintf(stderr,
00202                 "memstats: all-time: %llukiB in %lu requested allocations\n",
00203                 p->nbytes_alltime/1024, p->nallocations_alltime);
00204 
00205         fprintf(stderr,
00206                 "memstats: current: %lukiB in %lu active allocations\n",
00207                 (unsigned long)(p->nbytes_current/1024),
00208                 p->nallocations_current);
00209 }
00210 
00211 // ######################################################################
00212 struct env_rgb_pixel* env_stdio_parse_rgb(const char* fname,
00213                                           struct env_dims* outdims)
00214 {
00215         FILE* f = fopen(fname, "rb");
00216 
00217         if (f == 0)
00218                 lfatal("Couldn't open file '%s' for reading.", fname);
00219 
00220         int c = getc(f);
00221         if (c != 'P')
00222                 lfatal("Missing magic number in pnm file '%s'"
00223                        "(got '%c' [%d], expected '%c' [%d]).",
00224                        fname, c, c, 'P', 'P');
00225 
00226         int mode = -1;
00227         int ret = fscanf(f, "%d", &mode);
00228         if (ret > 0 && mode != 6)
00229                 lfatal("Wrong pnm mode (got 'P%d', expected 'P6')",
00230                        mode);
00231 
00232         while (1)
00233         {
00234                 const int c = getc(f);
00235                 if (!isspace(c))
00236                 { ungetc(c, f); break; }
00237         }
00238 
00239         // copy and concatenate optional comment line(s) starting with '#'
00240         // into comments string
00241 
00242         while (1)
00243         {
00244                 const int c = getc(f);
00245                 if (c != '#')
00246                 { ungetc(c, f); break; }
00247                 else
00248                 {
00249                         while (getc(f) != '\n')
00250                         { /* empty loop */ }
00251                 }
00252         }
00253 
00254         int w = -1;
00255         int h = -1;
00256         int maxGrey = -1;
00257         ret = fscanf(f, "%d %d %d", &w, &h, &maxGrey);
00258         ENV_ASSERT(ret > 0);
00259         ENV_ASSERT(w > 0);
00260         ENV_ASSERT(h > 0);
00261         ENV_ASSERT(maxGrey > 0);
00262 
00263         // read one more character of whitespace from the stream after maxGrey
00264         c = getc(f);
00265         if ( !isspace(c) )
00266                 lfatal("Missing whitespace after maxGrey in pbm file '%s'.", fname);
00267 
00268         struct env_rgb_pixel* result = (struct env_rgb_pixel*)
00269                 env_allocate(w * h * sizeof(struct env_rgb_pixel));
00270         if (fread((char*) result, 3, w*h, f) != ((env_size_t)(w*h)))
00271                 lfatal("%s: fread() failed", fname);
00272         outdims->w = w;
00273         outdims->h = h;
00274         return result;
00275 }
00276 
00277 // ######################################################################
00278 void env_stdio_write_gray(const struct env_image* iimage,
00279                           const char* outstem, const char* name, int c)
00280 {
00281         if (!env_img_initialized(iimage))
00282                 return;
00283 
00284         // if outstem is the empty string, then the user wanted us to
00285         // suppress output:
00286         if (outstem[0] == '\0')
00287                 return;
00288 
00289         char fname[256];
00290         snprintf(fname, sizeof(fname),
00291                  "%s-%s%06d.pnm", outstem, name, c);
00292 
00293         FILE* const f = fopen(fname, "wb");
00294         if (f == 0)
00295                 lfatal("%s: couldn't open PNM file for writing (errno=%d, %s)",
00296                        fname, errno, strerror(errno));
00297 
00298         if (fprintf(f, "P5\n%d %d\n255\n",
00299                     (int) iimage->dims.w, (int) iimage->dims.h) < 0)
00300                 lfatal("%s: fprintf() failed (errno=%d, %s)",
00301                        fname, errno, strerror(errno));
00302 
00303         const intg32* const src = env_img_pixels(iimage);
00304         const env_size_t sz = env_img_size(iimage);
00305         byte* bimage =
00306                 (byte*) env_allocate(sz * sizeof(byte));
00307 
00308         for (env_size_t i = 0; i < sz; ++i)
00309         {
00310                 // the caller is supposed to have already ensured that
00311                 // the intg32 image has been downsampled to a [0,255]
00312                 // range, so let's verify that:
00313                 ENV_ASSERT(src[i] >= 0 && src[i] <= 255);
00314                 bimage[i] = (byte) src[i];
00315         }
00316 
00317         if (fwrite(bimage, 1, sz, f) != sz)
00318         {
00319                 env_deallocate(bimage);
00320                 lfatal("%s: fwrite() failed (errno=%d, %s)",
00321                        fname, errno, strerror(errno));
00322         }
00323 
00324         env_deallocate(bimage);
00325 
00326         if (fclose(f) != 0)
00327                 lfatal("%s: fclose() failed (errno=%d, %s)",
00328                        fname, errno, strerror(errno));
00329 }
00330 
00331 // ######################################################################
00332 /* So things look consistent in everyone's emacs... */
00333 /* Local Variables: */
00334 /* indent-tabs-mode: nil */
00335 /* c-file-style: "linux" */
00336 /* End: */
00337 
00338 #endif // ENVISION_ENV_STDIO_INTERFACE_C_DEFINED
Generated on Sun May 8 08:40:38 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3