00:00:00,500 --> 00:00:03,640 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. Now what if instead of a whole number float, the user gives us 1.5 or 0.5? Well, it's impossible to write a pixel a fraction of a time. So let's adjust our thinking. Instead, how about for each pixel in the row, we simply write the corresponding pixel from the old row? It would look something like this. Here I have the same three pixels as before. Now we know that we need to scale by 1.5. So we know that the outfile row is going to have four pixels in it. So for each one of those four pixels in the outfile, I figure out what the corresponding pixel is. So see if you can figure out what pattern I'm using here. I'll use the same pattern for a float input of 0.5. With three pixels in the original row, I'll calculate that I'll need two pixels in my outfile row. So I'll calculate the corresponding pixel as follows. 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.