Laboratory: Representing Integers as Characters Summary: In this laboratory, you will explore ways to store images more efficiently by representing the data in an encoded form rather than in a human-readable form.
Preparation a. Review the previous lab. b. Add to your definitions pane the revised procedures created during that lab, image-write-pixmap and image-read-pixmap. If you don't have that code, or your don't trust your code, you can find sample solutions at the end of this lab. c. Add to your definitions pane the file-size and image-random-fill! procedures, also available at the end of this lab. d. Add to your definitions pane the first versions of rgb-write and rgb-read.
Exercises
Exercise 1: File Sizes a. Create a new 10x10 image named all-white, all of whose pixels are white. b. Using image-write-pixmap, save that image to a file named all-white.pixmap. c. How many characters do you expect to be in that file? d. Check your answer experimentally, using file-size. If you're not sure about why you got the number you did, you may want to open all-white.pixmap to look at what form it has. (That is, in MediaScript, select Open ... from the File menu, click on Show All, navigate to the file you just created, and select it.) e. Make a new 10x10 image, all-black, in which all of the pixels are black. (An easy way to do this is to first set the background color to black, and then create the new image.) f. Using image-write-pixmap, save that new image to all-black.pixmap. g. How many characters do you expect to be in that file? h. Check your answer experimentally, using file-size. If you're not sure about why you got the number you did, you may want to open all-black.pixmap to look at what form it has. i. Create another 10x10 image and name it random-colors. Fill the image with random colors, using image-random-fill!. j. Using image-write-pixmap, save that image to random-colors.pixmap. k. How many characters do you expect to be in that file? l. Check your answer experimentally, using file-size. If you're not sure about why you got the number you did, you may want to open random-colors.pixmap to look at what form it has. m. If you got different file sizes for the three files, explain why.
Exercise 2: File Sizes, Revisited a. Replace the definitions of rgb-write and rgb-read with the component-based human-readable versions below. b. Write the three images you created in Exercise 1 to three files, new-all-white.pixmap, new-all-black.pixmap, and new-random-colors.pixmap. c. Predict the size of each file. d. Check your predictions using file-size. e. Using these results, predict the size of a file for a 10x20 image of random pixels. f. Check your answer experimentally.
Exercise 3: Writing and Reading Integers as Data a. Add the definitions of int-write, int-read, and int-peek to your definitions pane. b. Using int-write, write five small, positive integers of your choice to a file named data. For example, > (define dataport (open-output-file "data")) > (int-write 6 dataport) > (int-write 17 dataport) > (int-write 64 dataport) > (int-write 32 dataport) > (int-write 42 dataport) > (close-output-port dataport) c. Predict the size of that file. d. Using file-size, determine the size of the file. e. Read the data back from the file using int-read. > (define inport (open-input-file "data")) > (int-read inport) 6 ... > (int-read inport) &eof; > (close-input-port inport) f. What do you expect to have happen if you read the data back from the file using read-char? g. Check your answer experimentally. > (define inport (open-input-file "data")) > (read-char inport) ... > (read-char inport) &eof; > (close-input-port inport) h. What do you expect to have happen if you read the data back from the file using read? i. Check your answer experimentally. > (define inport (open-input-file "data")) > (read inport) ... > (read inport) &eof; > (close-input-port inport) j. What do your results suggest about reading values from a file created by int-write?
Exercise 4: Reading Characters as Integers a. As you may recall, the file /home/rebelsky/glimmer/samples/hi.txt contains the text Hi There!. What do you expect to have happen if you use int-read to read from that file? b. Check your answer experimentally. > (define inport (open-input-file "/home/rebelsky/glimmer/samples/hi.txt")) > (int-read inport) ... > (int-read inport) &eof; > (close-input-port inport)
Exercise 5: Colors as Data We suggested in the reading that it is useful to represent colors as byte sequences, rather than in human-readable form. To do so, we need to make some changes to our code. a. List the changes you expect to have to make in order to use character encodings of integers, rather than human-readable text, for storing our images. b. Replace the definitions of rgb-write and rgb-read to the ones that use int-write and int-read. c. Update the definition of image-write-pixmap to (i) drop any calls to newline and (ii) use int-write to write the width and height. d. Update the definition of image-read-pixmap to use int-read to read the width and height. e. Using these updated versions, write and then read a small sample image. (Note that your old saved files won't work, because we changed the method for storing the data.)
Exercise 6: File Sizes, Re-Revisited In case you've forgotten, the point of all of this work was to write our images using smaller files. Let's see if our strategy worked, using the same examples we used before. a. Create three images, each 10x10, the first filled with all white pixels, the second with all black pixels, the third with random pixels. b. Write the three images to three files, newer-all-white.pixmap, newer-all-black.pixmap, and newer-random-colors.pixmap. c. Predict the size of each file. d. Check your predictions using file-size. e. Using these results, predict the size of a file for a random 10x20 image. f. Check your answer experimentally. g. Reflect on what you learned from all of today's work.
For Those With Extra Time The following extra exercises are repeated from the laboratory on pixmaps, as it is not likely that many students had the opportunity to do them in the first lab.
Extra 1: Reading Sections of Images Right now, when you read a pixmap into a larger image, it fills in the larger image, row-by-row, until you run out of colors. Instead, we could specify the section of the larger image to fill in. What should we specify? Presumably, the left edge, top edge, width, and height of the region to fill in. Write a procedure, (image-read-pixmap-region! image filename left top width height), that reads from a pixmap into a rectangular region in an image. For example, to read from a recently created image file into the 4x3 section starting at 5,7, we might write > (region-read-pixmap! big-canvas "image3.pixmap" 5 7 4 3) Your procedure should verify that the width and height stored in the pixmap file match the width and height of the region. Your procedure should also verify that the region is completely contained in the image.
Extra 2: Writing Sections of Images If we're willing to read pixmaps into sections of images, we might as well provide the converse operations: Writing pixmaps from sections of images. Write a procedure, (image-write-pixmap-region image file left top width height), that writes a region of an image to the specified file.
Explorations
As you've seen, the computer is willing to treat almost any file as data. That is, even if you've written text, you can read that text back as numbers. Here's a version of image-read-pixmap (renamed appropriately), that reads an image without paying attention to the size. Pick a few interesting text files (e.g., papers you've written, programs you've written for this class, assorted Web pages ) and turn them into images.
Notes
Useful Procedures These are procedures you should have written in the previous lab. They are included in case you are not sure about your answers or in case you were not able to complete that lab. These are procedures that you might find helpful as you do this lab.