Comp 2673 Spring 2003 Lab 2 Comp 2673
Spring 2003
Lab 2

This lab will give you some practice dealing with two-dimensional arrays. As usual, keep your directories on the Sun machines organized. You should have a directory for Comp 2673. Inside that directory, create a directory for lab 2. That's where you should store files you create today.

There are two concepts you should have clear before starting the lab. The first concept is how to use a one-dimensional array to store two-dimensional information. You already know that when you create a 2-D array statically, your code might look like this:

    unsigned char a[100][100];    // create a 100x100 array
    for (i=0; i < 100; i++)
        for (j=0; j < 100; j++)
            a[i][j] = 127;        // fill every position with a middle-gray 127
However, the above doesn't work if you don't know the size of the array at compile time. In that case, there are a few possibilities for how to do the memory allocation. Here's one:
    cout >> "Enter the height and width: ";
    cin >> h >> w;
    unsigned char a[h][w];       // create a wxh array
    for (i=0; i < h; i++)
        for (j=0; j < w; j++)
            a[i][j] = 127;       // fill every position with a middle-gray 127
The above method is easy to understand and works great until you want to pass the array to a function. You may recall that to pass a 2-D array to a function, the width of that array must be defined at compile time. Therefore, the following second method for allocating the array is preferable. In this method, we actually use a one-dimensional array to store two-dimensional data. The 2-D array is thus "flattened". Since the data in a 2-D array is stored in rows, we can calculate its position with a simple formula. The number at a[i][j] is actually stored in the (i*width+j)th position.
    cout >> "Enter the height and width: ";
    cin >> h >> w;
    unsigned char *a;              // a will point to our array
    a = new unsigned char[h*w];    // dynamically allocate h*w positions
    for (i=0; i < h; i++)
        for (j=0; j < w; j++)
            a[i*w+j] = 127;        // fill every position with a middle-gray 127

The second concept you need for this lab is about scaling images. There are lots of algorithms for making an image smaller. The very simplest can be used if you're shrinking the image by a whole number. If you're shrinking by a factor of 2, for example, then each pixel is calculating using exactly 4 pixels. To get its value, just average the values of the 4 relevant pixels. For example, say that we have an image that is 4x4 pixels with the following values:

         10  100  |  51  150
         200  50  |  51  250
         --------------------
         23   20  |  21   20  
         20   20  |  20   20
The resulting image (shrunk by a factor of 2) will be 2x2 pixels - the lines in the above array show you which groups of 4 to average to get each of the resulting pixels. Here's what you get (make sure you understand how these were calculated, including rounding):
         90   126 
         21   20
Now you're ready to do the lab!
  1. Download the file lab2.cpp, bmp.cpp, bmpread.cpp, bmp.h and bush.bmp.
  2. Read the code in lab2.cpp. It is an incomplete program whose purpose is to scale down a bitmap image by a factor of 2. You need to add some code to do the scaling.
  3. Compile the program by typing g++ bmp.cpp bmpread.cpp lab2.cpp -o shrink
  4. Run the program (by typing its name, shrink). Use the file bush.bmp as a test file. As another test file, use the gray image with a black x that you created last week.
  5. View the original image and your scaled image using xv.
  6. Turn in your code and a printout of the scaled image.