contrib/oul/ouml/image_database.cxx

Go to the documentation of this file.
00001 //-*-c++-*--------------------------------------------------------------
00002 /**
00003  * \file
00004  *
00005  * An image database. Basically maintains a list of labels and
00006  * associated images. And allows for saving and loading a database. 
00007  * Ideally, this would form an inheritance hierarchy or be a templated
00008  * class, but I'm looking for simplicity at the moment.
00009  *
00010  * The images inserted into the database WILL be deleted on
00011  * destruction of the database. So only insert things you don't want
00012  * to persist.
00013  *
00014  * \author Brendan McCane
00015  * \date 17/7/01
00016  *
00017  * Copyright (c) 2001 Brendan McCane
00018  * University of Otago, Dunedin, New Zealand
00019  * Reproduction rights limited as described in the COPYRIGHT file.
00020  */
00021 //----------------------------------------------------------------------
00022 
00023 #include "image_database.h"
00024 #include <vcl_iostream.h>
00025 #include <vcl_cerrno.h> // for EEXIST
00026 #include <vcl_cctype.h> // for tolower()
00027 #include <vcl_cstdio.h> // for fscanf()
00028 #include <vcl_algorithm.h> // for transform()
00029 #include <vpl/vpl.h> // for vpl_mkdir
00030 #include <vil1/vil1_load.h>
00031 #include <vil1/vil1_save.h>
00032 
00033 //----------------------------------------------------------------------
00034 /** destructor
00035  *
00036  * Iterate through all images in the database and delete them.
00037  *
00038  * \side Memory is actually deallocated
00039  *
00040  * \author Brendan McCane 
00041  */
00042 //----------------------------------------------------------------------
00043 
00044 ImageDatabase::~ImageDatabase()
00045 {
00046   clear();
00047 }
00048 
00049 //----------------------------------------------------------------------
00050 /** clear
00051  *
00052  * clear all the images from the database (deletion is performed)
00053  *
00054  * \author Brendan McCane 
00055  */
00056 //----------------------------------------------------------------------
00057 void ImageDatabase::clear()
00058 {
00059   for (iterator i=begin(); i!=end(); i++)
00060   {
00061     delete (*i).second;
00062   }
00063   image_db.clear();
00064 }
00065 
00066 //----------------------------------------------------------------------
00067 /** save
00068  *
00069  * Save all images in the database. To do this, I create a single
00070  * database file that has a list of label/filename pairs. I also
00071  * create a subdirectory in which all the images are stored. The
00072  * images are stored based on the imagetype parameter, which should be
00073  * the extension of a valid image file type (eg "ppm", "pgm", "png",
00074  * etc).
00075  *
00076  * \param name  the name of the database file (a directory called name.d is also created).
00077  *
00078  * \param imagetype  a valid file extension type (eg "ppm");
00079  *
00080  * \author Brendan McCane 
00081  */
00082 //----------------------------------------------------------------------
00083 
00084 bool ImageDatabase::save(const char *name, const char *imagetype)
00085 {
00086   char dirname[200];
00087   vcl_sprintf(dirname, "%s.d", name);
00088 
00089   int err;
00090 
00091   err = vpl_mkdir( dirname, 0755 );
00092   if (err != 0 && err != EEXIST)
00093   {
00094     vcl_cerr << "can't open directory " << dirname << vcl_endl;
00095     return false;
00096   }
00097 
00098   // now open the database file
00099   FILE *dbfile;
00100   if (!(dbfile=vcl_fopen(name, "w")))
00101   {
00102     vcl_cerr << "Can't open database file " << name << vcl_endl;
00103     return false;
00104   }
00105 
00106   int index=0;
00107   for (iterator i=begin(); i!=end(); i++)
00108   {
00109     char filename[200];
00110     vcl_sprintf(filename, "%s/%s_%03d.%s", dirname, (*i).first, index++, imagetype);
00111     vil1_save(*((*i).second), filename);
00112 
00113     vcl_printf("db: %s %s\n", (*i).first, filename);
00114     vcl_fprintf(dbfile, "%s %s\n", (*i).first, filename);
00115   }
00116   vcl_fclose(dbfile);
00117   return true;
00118 }
00119 
00120 
00121 //----------------------------------------------------------------------
00122 /** load
00123  *
00124  * Load a database from file. 
00125  *
00126  * \param name  the name of the database file (a directory called name.d should also exist).
00127  *
00128  * \author Brendan McCane 
00129  */
00130 //----------------------------------------------------------------------
00131 
00132 bool ImageDatabase::load(const char *name)
00133 {
00134   // now open the database file
00135   FILE *db;
00136   if (!(db=vcl_fopen(name, "r")))
00137   {
00138     vcl_cerr << "Can't open database file " << name << vcl_endl;
00139     return false;
00140   }
00141 
00142   char label[200], filename[200];
00143   while (vcl_fscanf(db, "%s%s", label, filename)!=EOF)
00144   {
00145     vil1_image im = vil1_load(filename);
00146     if (!im) return false;
00147     vil1_memory_image *image = new vil1_memory_image(im);
00148     insert(label, image);
00149   }
00150   vcl_fclose(db);
00151   return true;
00152 }
00153 
00154 bool ImageDatabase::ltstr::operator()(const char* s1, const char* s2) const
00155 {
00156   // do a case insensitive comparison. Can't use strcasecmp
00157   // because it's not standard.
00158   vcl_string tmp1( s1 );
00159   vcl_string tmp2( s2 );
00160   vcl_transform( tmp1.begin(), tmp1.end(), tmp1.begin(), ::tolower );
00161   vcl_transform( tmp2.begin(), tmp2.end(), tmp2.begin(), ::tolower );
00162   return vcl_strcmp( tmp1.c_str(), tmp2.c_str() ) < 0;
00163 }

Generated on Tue Dec 2 05:25:34 2008 for contrib/oul/ouml by  doxygen 1.5.1