ZAMYLA CHAN: Let's scale things up with resize.
In resize, the user will provide us with a float
by which they want to scale their infile and the name for an outfile image.
It's up to us to parse that float input, update the outfile's header
information, and then resize our bitmap accordingly,
either making it smaller or larger than before.
If we look at the distribution code, then we'll
see that the implementation of copy.c satisfies
a lot of similar functionalities to that of resize.
copy.c will parse an integer input, then open your infile
and outfile, updating the header information for your outfile
and reading into the infile scanline pixel
by pixel, writing those pixels into the output file.
So perhaps our first step would be to copy copy.c into resize.c.
But we need to parse floats not integers.
So check out the sscanf function and the atof function.
Also make sure to check out corner cases, perhaps
taking a peek into CS50's own get float function for more hints.
Then we need to update the outfile's header information.
Now, bitmaps are simply an arrangement of bytes just like any other file.
It's just a matter of how we interpret this arrangement.
So take a look into bmp.h for some documentation.
Essentially whenever we have a new bitmap,
we'll need to update the header information.
So what's changing when we're scaling up or scaling down?
Well, the file size is going to change as does the image size, the width,
and the height of our bitmap.
In the bitmap info header, we have the biWidth,
which includes the width of the image in pixels not including
padding, and the biHeight, the height of the image in pixels.
We also have the biSizeImage, which is the total size of the image in bytes
including the pixels and the padding.
Moving to the bitmap file header, we have
bfSize which contains the total size of the file in bytes.
So that includes pixels, padding, and the headers.
So of these values, what's changing when we scale our bitmap up or down
by a factor of f?
Well, biWidth and biHeight will definitely scale by f.
So figure out how biSizeImage and bfSize are also going to change.
Now that we've updated the outfile's header information, let's talk
about resizing horizontally.
So say the user gave us a float of 2.
Well then, the algorithm would be pretty simple.
For each pixel in the row, we would write that pixel f times
into the outfile row.
All right, so now that we've figured out that pattern,
let's talk about the two functions that we'll need to use.
To read into the file, we'll use the fread function.
And then to write the files, we'll use fwrite.
So the next thing that we need to talk about is padding.
In a bitmap, every pixel is three bytes long.
Now, a requirement for the bitmap image is that the length of each scanline
must be a multiple of four bytes.
So if the number of pixels is not a multiple of four,
then we'll need to add padding where padding is just a single zero
character.
In this example, I have 4 pixels in my row.
Now, with 4 pixels 3 bytes each, that equates to 12 bytes.
So I won't need to add any padding.
But instead, if I had 5 triples, then 5 times 3 is 15, not a multiple of 4.
So I'd need to add one single padding character.
Then if I had six RGBtriples, I'd add 2 characters of padding.
Finally, with 3 RGBtriples, I'd add 3 units of padding.
I've included the equation for padding here.
And it can also be found in the problem specification.
Notice how padding depends on width of the bitmap
and the size of an RGBtriple.
Now the size of the RGBtriple is going to be constant.
So the only thing that might be changing is the width of the bitmap.
So if the outfile and infile have different widths,
then they may have a different amount of padding.
Remember our discussion about bitmap headers
where we calculated how the old header information might
change for the outfile.
Well, because the padding is going to be different for the infile
and the outfile, then we may also need to keep track of that as well.
Now, why do we keep track of both the old and the new padding?
Well, we'll need the old padding because we'll
want to skip over the padding in the infile using fseek.
And then we need to know how much padding to add into the outfile.
And we'll use fputc to put those characters in.
Now that we have a firm grasp on padding,
we can resize our entire image.
So once we figure out which row should be written, then let's seek to that,
draw the pixels into the outfile and write the outfile's padding.
With that, we've resized our image.
My name is Zamyla.
And this was resize.