Introduction
This lab will provide practice using Matrices, manipulating images, and data compression. It will serve as an introduction to the third programming assignment. Be sure that you have created a "cps100e" subdirectory. If you haven't and don't know how, be sure to ask a TA for help. It's a good idea to make the directory readable by the professors teaching the course and by your lab TA. To do this you can type what's shown below (and substitute any login-id for "ola").
fs setacl cps100e ola read
Change into your "cps100e" directory and create a "lab4" subdirectory (use "mkdir lab4"). Then change into this and copy files by typing what's below (don't forget the trailing dot).
cp ~ola/cps100e/lab4/* .
From the "lab4" subdirectory, make a link to several image files. To do this type
ln -s ~ola/data/images images
Then you'll be able to use the directory "images" to access several image files. You can type "ls images" to see what's in it.
If you type "ls" you should see the following files: "Makefile", "usepix.cc", "pixmap.h", "pixmap.cc" (and "images" which is a link).
Use the menu-bar to invoke emacs or type "emacs &" to get an emacs window. You want to use the ampersand & which leaves you with control of your xterm (so you can run programs from it). Be sure to leave the emacs window up, don't quit it until you log off.
Displaying Images
Use the emacs commands "C-x C-f" to find/load the file "usepix.cc". Then compile this command using "C-x c" and type "make usepix" in the minibuffer. If this doesn't invoke the compile command you can always type "M-x compile" (that's ESCAPE-x compile).
When the program runs, you'll be presented with a menu of options. Choice "(l)oad" (press 'l') and specify the directory "images". Then load "abstract.pbm". Then choose the "(d)isplay" option. This will pop a window run by the program XV. To make the window disappear, and to control pass back to your program, type 'q' when the mouse-cursor is in the displayed image.
You can try other options and pictures, you will be implementing some of the options that are not currently implemented.
Pixmap Member functions
You will implement two "Pixmap" member functions: "Invert" and "VertReflect".
The function "Pixmap::Invert" should turn all black pixels to white and all white pixels to black. Ideally, the function should work for gray-scale images too. To invert, you'll need a nested loop to run over all the cells in the matrix "myMap.image". To change black to white (and "vice-versa") you COULD use an if/else statement based on the line below.
if (myMap.image[j][k] == 0) myMap.image[j][k] = 1;
However, you can also do this by noticing that 1 - 0 = 1 and 1 - 1 = 0. Think of 0 as white and 1 as black. In other words, subtracting a pixel value from 1 always yields the ``opposite'' pixel value (e.g., 1 - white = black). Instead of subtracting from 1, you can subtract from "myGrayLevel" which stores the largest grayscale value (the default value is 1, see "Pixmap::Read").
The function "Pixmap::VertReflect" reflects the image in a vertical line running through the center of the image. This essentially reverses every row of the image. To do this, you'll need a loop to reverse every row. You should look at the logic in "Pixmap::HorizReflect", think about what it's doing, and mimic this logic in "Pixmap::VertReflect". Be sure to test your reflection function.
Reading Compressed files
Files that end with the ".cbm" suffix are compressed bitmap files. These are compressed using run-length encoding, where a sequence of 1's (or 0's) is replaced by the length of the sequence. For example, the sequence on the left would be compressed into the sequence on the right.
0 0 0 0 0 0 1 1 0 6 2 4 5 7 3
0 0 0 1 1 1 1 1 0
0 0 0 0 0 0 1 1 1
Note that the first sequence of six zero's is replaced by its length, followed by 2 ones, 4 zeros, 5 ones, 7 zeros, and 3 ones. "All compressed" files start with a run of zeros (if there are no zeros at first the length of the run is 0, but the 0 is stored).
To read these compressed files in, you'll need to add code to the "Pixmap::Read" member function. You need to add a statement to increment "c" by 1 (to go to the next column) and a single "if" statement, with two statements inside the if, in the place marked "fill in here". The idea is that if the value of "c" gets too big (past the last column of the matrix) then you'll need to reset "c" to the first column and move to the next row. This will change both "c" and "r".
If you get this right, you can test by trying to read in "mystery.cbm" or "mystery2.cbm".
Readme
You'll need to explain what several lines in "usepix.cc" do. Put the answers to these three questions in your README file.
files[numFiles] = dir.Current().Name();
Explain the value "dir.Current().Name()", why are there two sets of parentheses?
ofstream output(s); // open output file stream
We've seen the use of "open" to open a file stream using "output.open(s)". Explain the line above that does not use "open", but still opens an output file stream.
system("/bin/rm -f " + tempName); // remove temp file
Try to explain what's going on here and in the function "DoDisplay" in general (you can guess, but try --- getting it right isn't important).
Submission
To turn in programs: When your modified program works, you can submit them, along with a README describing how long it took you, what your impressions of the lab are, and the answers to the questions posed above. If you edit the Makefile, you can type "make submit" to submit the appropriate files, or you can type the command below. Be sure to submit for the appropriate section, e.g., type "lab4sec1" if you are in section 1.
submit100e lab4sec2 README pixmap.cc
The README file should include your name, how long you worked on the program, and anyone you received significant help from. You should also include any comments you have about the lab.
You should receive a message telling you that the programs were submitted correctly. If you get a message indicating that "submit100e" isn't found, you can always type the full path name:
~ola/bin/submit100e lab4sec2 README pixmap.cc