#include #include #include #include "CPstring.h" #include "pixmap.h" #include // for tolower #include // for atoi #include "directory.h" #include "vector.h" #include // skeleton driver program for bitmap program // Owen Astrachan for CPS 08 // written: 11/3/93 // revised: 11/28/94 // revised: 04/13/95 // // rewritten for CPS 100E, fall 1995 // revised: 9/25/1995 (matrix and vector classes used) // temporary file used to drive system call of xv // enum Operation {invert,vertical,horizontal,expand,enhance}; // prototypes for Do functions void DoLoad(Pixmap &); void DoSave(const Pixmap &); void DoCompress(const Pixmap &); void DoOperation(Pixmap &, Operation); void DoDisplay(const Pixmap &); void DoQuit(); // array of choices/operations // these should match up so that Choices[k] is character for Operations[k] // numOps is the number of entries in Choices (and in Operations) char Choices [] = { 'l','s','c','d','i','v','h','e','x','?','q' }; string Operations [] = { "(l)oad an image (bitmap/grayscale/compressed)", "(s)ave an image (bitmap/grayscale)", "(c)ompress and save (run-length encoding)", "(d)isplay current image (using xv)", "(i)nvert image", "(v)ertical reflect (along vertical axis)", "(h)orizontal reflect (horizontal axis)", "(e)nhance (median filter)", "e(x)pand and image", "(?) help (print menu)", "(q)uit program" }; const int numOps = sizeof(Choices)/sizeof(char); const int QUIT_CHAR = 'q'; void PrintMenu() { int k; for(k=0; k < numOps; k++) { cout << " " << Operations[k] << endl; } } main() { string s; char ch = '?'; // initialize to something Pixmap pix; do { PrintMenu(); cout << endl << "enter choice "; getline(cin,s); if (s != "") // something read { ch = tolower(s[0]); // first char of command } switch(ch) { case 'l': DoLoad(pix); break; case 's': DoSave(pix); break; case 'c': DoCompress(pix); break; case 'i': DoOperation(pix,invert); break; case 'v': DoOperation(pix,vertical); break; case 'h': DoOperation(pix,horizontal); break; case 'e': DoOperation(pix,enhance); break; case 'x': DoOperation(pix,expand); break; case '?': PrintMenu(); break; case 'd': DoDisplay(pix); break; case 'q': DoQuit(); break; default: cout << "unknown option: " << ch << ", re-enter" << endl; break; } } while (ch != QUIT_CHAR); } bool IsBitmapFile(const string & name) // postcondition: returns true if name contains a legal image suffix // e.g., pbm, pgm cbm ... { //legal suffixes static string suffixTable[] = {".pbm", ".pgm", ".cbm"}; const int MAX_TABLE = sizeof suffixTable / sizeof suffixTable[0]; int k; for (k=0; k & files, int & numFiles, int startIndex) // // precondition: store new elments in files starting with index startIndex // Postconditions: numFiles contains the number of file entries added to // the Vector of strings (files) // files[startIndex]...files[startIndex+numFiles-1] have // been added { DirStream dir; //Directory stream DirEntry entry; //Directory entry int nIndex = startIndex; //current index in vector string name; //name of current file numFiles = 0; dir.open(base); if (! dir) { cerr << "could not open directory " << base << endl; return; } for(dir.First(); !dir.IsDone(); dir.Next()) { if (! dir.Current().IsDir()) { name = dir.Current().Name(); if (IsBitmapFile(name)) { if (nIndex >= files.Length()) { files.SetSize(files.Length()*2); // grow the vector } files[nIndex] = name; numFiles++; nIndex++; } } } } void DoLoad(Pixmap & pix) // postcondition: pix loaded from user-specified file { string s; const string base = "/u/o/l/ola/data/images"; // images directory const string curr = "."; // current directory int numBase = 0; //# of files in images directory int numCurr = 0; //# of files in current directory int numFiles = 0; Vector files(20); LoadDirectory(base, files, numBase, 0); LoadDirectory(curr, files, numCurr, numBase); numFiles = numBase + numCurr; cout << " ****** files *****" << endl << endl; int k; for(k=0; k < numFiles; k++) { cout << "(" << k << ") " << files[k] << endl; } cout << endl << "enter choice> "; getline(cin,s); k = atoi(s); if (0 <= k && k < numFiles) { string filename; if (k