This is a simple assignment to reinforce accessing the lab systems remotely, compiling on the command line, simple I/O, and using ASCII to process chars as ints
This is mostly verbatim from Dr. Plank's version, since it was recommended by Dr. Marz to "onboard" you into 140. I also expect it to be finishable in lab using our lecture notes. My main function is roughly 10 lines, excluding blank lines.
Originial version here: http://web.eecs.utk.edu/~jplank/plank/classes/cs140/Labs/Lab2
Unfortunately, most web browsers do not have support for PGM files. However, every environment has many ways of dealing with them. For example, Photoshop, Open Office and Gimp both support them as image types. Dr. Plank guesses that iphoto and whatever photo editor comes with Windows handles them as well.
Most Unix environments have a program called convert, which will convert pgm's to jpgs for easy viewing. For example, on our labs:
UNIX> cp /home/jplank/cs140/Labs/Lab2/Nigel.pgm . UNIX> convert Nigel.pgm Nigel.jpgYou may now view Nigel.jpg with a web browser. Test it out. It should look like:
Here are a bunch of sample images drawn from three different sources: a professor at Florida State (first row), my simulation of what you'd do using an online tool (second row), and from Dr. Plank (third row).
You'll note that the ones I created are not really PGM files... they have "P5" as a header and are actually a binary format you ** can not ** read using the standard cin framework(s) we discuss in class. They can still be converted into JPGs (see above) but are pretty useless as actual input for this lab. I'll instruct the TAs to provide their favorite PGMs but will let you know I personally used red.pgm to test my answer to this lab (first in 2018, then again this semester). So don't create your own PGM files as its likely to not work. Also, note that the sizes of the JPG pictures below do not match the PGM files (e.g., the planet ones). They've been shrunk somewhat to make them display better.
Venus2.pgm (credit Florida State, Prof. Burkardt) |
Saturn.pgm (credit Florida State, Prof. Burkardt) |
art.pgm My hometown... youse probably know these better from Rocky movies (photo credit Philly Inquirer) |
loyola.pgm Where I took most of my non-CS classes in college | Red.pgm Red Forman from original (and no, if you were wondering I was not alive in the 70s.. but did watch this show when it first came out in college) |
Dragon.pgm A super cute dragon, who doesn't like them (credit Florida State, Prof. Burkardt) |
You can find more PGMs of Dr. Plank's "role models" here.
A picture is simply a two-dimensional array of pixels. In a PGM file, a pixel is a gray value between 0 and 255. Zero is black, and 255 is white. Everything in between is a different shade of gray.
PGM files have a specific format. (Actually, they are more robust than this -- I've removed comments to make them easier for you). A PGM file is composed of words. The first word is ``P2''. Then the next two words define the number of pixels in the picture -- first is the number of columns in the two-dimensional array, and then the number of rows. The next word is the number 255. So, if you look at the beginning of Red.pgm, you'll see:
UNIX> head Red.pgm P2 235 183 255 67 74 76 80 76 77 70 67 75 82 102 119 129 133 130 127 128 130 134 131 130 129 130 133 132 125 116 109 101 102 105 105 113 119 128 133 138 137 137 137 141 143 143 144 140 143 146 144 140 138 128 122 118 107 106 104 106 107 115 124 127 121 114 108 103 98 97 108 122 138 140 140 139 129 123 125 127 141 145 147 147 146 147 147 147 149 150 150 150 155 168 185 195 198 202 201 201 200 200 199 201 199 200 201 207 205 206 203 204 205 206 206 205 206 207 207 207 207 207 UNIX>This means that Red.pgm is a 183 * 235 array of pixels. After the 255 come all the pixels. First, the pixels in the top row, then the pixels in the next row, etc. Note that the ASCII formatting of the file doesn't mean anything -- there could be one pixel per line and the file would still be a legal PGM file. In Red.pgm above, the first 235 pixels are those in the top row, then the next 235 are in the second row, and so on. There will be a total of 183*235 = 43005 pixels. After the last pixel, the file ends.
Before you go any further, create a PGM file of your own -- make it 10x10 and give the pixels any value you want. Take a look at it. Something like:
P2 10 10 255 0 10 20 30 40 50 60 70 80 90 10 20 30 40 50 60 70 80 90 100 20 30 40 50 60 70 80 90 100 110 30 40 50 60 70 80 90 100 110 120 40 50 60 70 80 90 100 110 120 130 50 60 70 80 90 100 110 120 130 140 60 70 80 90 100 110 120 130 140 150 70 80 90 100 110 120 130 140 150 160 80 90 100 110 120 130 140 150 160 170 90 100 110 120 130 140 150 160 170 180 |
This should look like:
Cool, no?
Here is an example of pgminfo running on some of the PGM files. Note, Dr. Plank has included in his set a few bad PGM files in Bad-1.pgm, etc. You need to make sure that your output matches mine exactly. And I mean exactly, meaning the same punctuation, same number of spaces, and same capitalization. Use printf(), not cout.
UNIX> ./pgminfo < Red.pgm # Rows: 183 # Columns: 235 # Pixels: 43005 Avg Pixel: 120.142 UNIX> ./pgminfo < Pike.pgm # Rows: 235 # Columns: 197 # Pixels: 46295 Avg Pixel: 99.932 UNIX> ./pgminfo < Bad-2.pgm Bad PGM file -- No column specification UNIX> ./pgminfo < Bad-5.pgm Bad PGM file -- pixel 99 is not a number between 0 and 255 UNIX> ./pgminfo < Bad-6.pgm Bad PGM file -- Extra stuff after the pixels UNIX>When I print a pixel number, it is zero-indexed. So the first pixel is pixel zero.
UNIX> ./bigwhite 20 10 > a.pgmThis will create a PGM file a.pgm, which has 20 rows and 10 columns of white pixels.
Your output in this and the next three programs should match mine exactly when there is an error. Otherwise, the PGM files that it emits should be equivalent to mine (they should make the same picture), but do not have to have the same output exactly.
For example, here is the negative of Red.pgm:
You'll have to use a vector for this program.
Here's the hflip of Red.pgm:
tar -cvf lab2.tar bigwhite.cpp hflip.cpp neg.cpp pgminfo.cppBased on ongoing discussion with the grad TAs, and especially the undergrads who have taken 140/302 largely in a pandemic, we will use Dr. Plank's gradescripts for this lab. As mentioned in class on Thursday these scripts prepare you well for later courses at UTK and for code tests, and all of team 140 felt strongly to do so. It also makes grading transparent and gets you in the habit of using Unix and debugging (also see recent Piazza posts on specific test cases that are more in depth than the "make test" used for Lab 1 and the challenge.
In exchange, I'll make the in-class challenge tests more basic
(i.e., less time checking edge conditions/input) and focused more
on syntax and concepts. We'll also have less automated testing for
at least one more lab (Lab 3) to help you get the hang of things.
I'll post a rubric in a minute -- which is consistent with Piazza and lab
traffic -- but most if not all points will be obtained from passing the
75 gradescripts for this assignment.