1 00:00:00,000 --> 00:00:10,210 >> [MUSIC PLAYING] 2 00:00:10,210 --> 00:00:13,320 >> ZAMYLA CHAN: Let's blow things up with resize. 3 00:00:13,320 --> 00:00:17,710 In resize, the user will pass in, via the command line, a bitmap image that 4 00:00:17,710 --> 00:00:21,860 they want you to scale by a number that they also pass in, 5 00:00:21,860 --> 00:00:23,770 in the command line. 6 00:00:23,770 --> 00:00:24,690 How do we do this? 7 00:00:24,690 --> 00:00:28,270 >> Well, first things first, let's break this down into steps. 8 00:00:28,270 --> 00:00:31,510 You're going to want to open the infile that they give you, as well as 9 00:00:31,510 --> 00:00:35,560 create and open the outfile that you're going to put the 10 00:00:35,560 --> 00:00:38,020 resized image in. 11 00:00:38,020 --> 00:00:42,050 Then, because you're resizing, and because it's a bitmap, it a header, so 12 00:00:42,050 --> 00:00:46,080 you're going to also update the header information for the outfile, 13 00:00:46,080 --> 00:00:47,950 and write that in. 14 00:00:47,950 --> 00:00:51,850 Then, you're going to read into the scanline of the infile, 15 00:00:51,850 --> 00:00:56,890 pixel-by-pixel, resizing horizontally and writing those pixels into the 16 00:00:56,890 --> 00:01:00,910 outfile, as specified by the user's scale. 17 00:01:00,910 --> 00:01:03,940 >> You're going to remember to add padding as necessary. 18 00:01:03,940 --> 00:01:05,400 More on that later. 19 00:01:05,400 --> 00:01:07,790 And then, also resize vertically. 20 00:01:07,790 --> 00:01:08,890 OK. 21 00:01:08,890 --> 00:01:13,280 So this is going to be a little bit more complicated than Who Done It, but 22 00:01:13,280 --> 00:01:18,310 what's similar is that copy.c will, again, prove very useful. 23 00:01:18,310 --> 00:01:23,160 Remember that copy.c opens a file, updates the header information for the 24 00:01:23,160 --> 00:01:28,250 outfile, then reads into the scanline, pixel-by-pixel, writing every pixel 25 00:01:28,250 --> 00:01:30,510 into the output file's scanline. 26 00:01:30,510 --> 00:01:37,040 >> So again, your first step might probably be to cp, copy.c, resize.c 27 00:01:37,040 --> 00:01:40,560 into your PSET5 directory. 28 00:01:40,560 --> 00:01:43,920 Remember though, before you copy it, to make sure that you understand 29 00:01:43,920 --> 00:01:46,600 copy.c very thoroughly. 30 00:01:46,600 --> 00:01:47,620 OK. 31 00:01:47,620 --> 00:01:49,880 >> So let's open a file. 32 00:01:49,880 --> 00:01:50,870 You know how to do that. 33 00:01:50,870 --> 00:01:52,600 I'm going to leave that to you. 34 00:01:52,600 --> 00:01:56,050 Next, update the header information for the outfile. 35 00:01:56,050 --> 00:01:59,240 Because we have a new bitmap, we have new header info. 36 00:01:59,240 --> 00:02:00,970 What's changing here? 37 00:02:00,970 --> 00:02:06,000 Well, the file size is going to change because we're going to have more 38 00:02:06,000 --> 00:02:07,900 pixels than before. 39 00:02:07,900 --> 00:02:11,060 The image size is, thus, also going to change, as is the 40 00:02:11,060 --> 00:02:13,050 width and the height. 41 00:02:13,050 --> 00:02:17,180 >> So which variables are those, exactly? 42 00:02:17,180 --> 00:02:20,960 Well, if you look into the header information, you see there is 43 00:02:20,960 --> 00:02:25,640 biSizeImage, which represents the total size of the image in bytes, 44 00:02:25,640 --> 00:02:28,340 including pixels and padding. 45 00:02:28,340 --> 00:02:32,520 biWidth is the width of the image in pixels, minus the padding. 46 00:02:32,520 --> 00:02:35,580 biHeight is the height of the image in pixels. 47 00:02:35,580 --> 00:02:39,200 And so those are contained in the structs BITMAPFILEHEADER and 48 00:02:39,200 --> 00:02:40,390 BITMAPINFOHEADER. 49 00:02:40,390 --> 00:02:45,300 You can tell which one is which by going to bmp.h and looking at the 50 00:02:45,300 --> 00:02:49,670 BITMAPINFOHEADER struct and seeing which variables are listed there. 51 00:02:49,670 --> 00:02:54,700 >> So to update the outfiles header information, you're going to want to 52 00:02:54,700 --> 00:02:57,025 change those values of the height and the width. 53 00:02:57,025 --> 00:03:00,570 But chances are, you might need some of the infile's header information 54 00:03:00,570 --> 00:03:03,670 later, so best to keep track of both. 55 00:03:03,670 --> 00:03:07,770 But be very clear with your variable names so that you don't accidentally 56 00:03:07,770 --> 00:03:12,490 write the incorrect values in the header for the outfile. 57 00:03:12,490 --> 00:03:16,160 >> So now let's get to reading into the scanline pixel-by-pixel. 58 00:03:16,160 --> 00:03:20,210 Again, we're going to turn to our trusty file I/O library, and look at 59 00:03:20,210 --> 00:03:22,100 the fread function. 60 00:03:22,100 --> 00:03:26,150 fread takes in a pointer to a struct that will contain the bytes that 61 00:03:26,150 --> 00:03:30,130 you're reading in, the size of each element that you're reading-- 62 00:03:30,130 --> 00:03:34,410 again, sizeof is going to be useful function here, the number of the 63 00:03:34,410 --> 00:03:38,820 elements of size, size, that you're reading in, and then finally, the 64 00:03:38,820 --> 00:03:41,310 inpointer, the file that you're reading from. 65 00:03:41,310 --> 00:03:46,770 So you're taking number elements of size from inpointer, and 66 00:03:46,770 --> 00:03:49,040 putting them into data. 67 00:03:49,040 --> 00:03:51,695 >> Now it's time to resize horizontally. 68 00:03:51,695 --> 00:03:56,880 if n equals 2, then for each pixel in the infile, we're going to write it 69 00:03:56,880 --> 00:04:00,870 twice in the outfile. 70 00:04:00,870 --> 00:04:02,210 How do we write files? 71 00:04:02,210 --> 00:04:06,400 Well, we have the fwrite function, so we've taken the pointer to the struct 72 00:04:06,400 --> 00:04:10,170 that contains the bytes that you're writing from, and then we pass in 73 00:04:10,170 --> 00:04:14,430 size, number, and the output, where you're going to be writing that. 74 00:04:14,430 --> 00:04:19,200 And then to repeat a process, will be able a simple iterative for loop. 75 00:04:19,200 --> 00:04:21,740 >> But we need to remember to add padding in. 76 00:04:21,740 --> 00:04:26,040 The concept of padding is that, well, each pixel is three bites, but the 77 00:04:26,040 --> 00:04:28,940 size of each scanline must be a multiple of 4 bytes. 78 00:04:28,940 --> 00:04:33,660 So if the number of pixels isn't a multiple of 4, we need to add some 79 00:04:33,660 --> 00:04:36,630 padding, which is just zeroes. 80 00:04:36,630 --> 00:04:42,130 Now, unlike Who Done It, and unlike copy, then infile image and the 81 00:04:42,130 --> 00:04:44,370 outfile file have different have different padding because they're 82 00:04:44,370 --> 00:04:46,360 different widths. 83 00:04:46,360 --> 00:04:46,690 >> OK. 84 00:04:46,690 --> 00:04:51,050 So perhaps a formula would come in handy here. 85 00:04:51,050 --> 00:04:55,120 I'll leave it to you to find it out, but tell you that, to write padding, 86 00:04:55,120 --> 00:04:59,360 well, it's just a simple fputc function, passing in the character 87 00:04:59,360 --> 00:05:02,200 that you want to write, and then the file pointer that you 88 00:05:02,200 --> 00:05:04,280 want to write to. 89 00:05:04,280 --> 00:05:08,670 So now that we've resized horizontally, and then used padding, 90 00:05:08,670 --> 00:05:12,030 remember that you need to move your file position indicator, because you 91 00:05:12,030 --> 00:05:14,480 can't fread into padding. 92 00:05:14,480 --> 00:05:18,230 So you want to make sure that your file position indicator in the infile 93 00:05:18,230 --> 00:05:19,980 is at the correct point. 94 00:05:19,980 --> 00:05:23,970 Because we also want to resize vertically. 95 00:05:23,970 --> 00:05:27,090 We can't just stretch it horizontally, because every row needs 96 00:05:27,090 --> 00:05:30,370 to be copied n times. 97 00:05:30,370 --> 00:05:33,050 >> Now, there are several different ways to do this. 98 00:05:33,050 --> 00:05:39,010 So one, we can use a rewrite method, in that we remember all of the pixels 99 00:05:39,010 --> 00:05:42,840 of a given row in an array, and then we write that array as 100 00:05:42,840 --> 00:05:44,730 many times as needed. 101 00:05:44,730 --> 00:05:49,530 Or there's the recopy method where, after reading in one row in the infile 102 00:05:49,530 --> 00:05:53,530 and then writing that into the outfile, adding the padding, we fseek 103 00:05:53,530 --> 00:05:57,250 back to the start of the original row, and then repeat the horizontal 104 00:05:57,250 --> 00:05:58,710 resizing from there. 105 00:05:58,710 --> 00:06:02,280 Regardless of the method, though, you'll want every pixel to be repeated 106 00:06:02,280 --> 00:06:06,370 n times, and every row to be repeated n times as well. 107 00:06:06,370 --> 00:06:09,160 >> With that, you'll have bitmap larger than life. 108 00:06:09,160 --> 00:06:11,760 My name is Zamyla, and this is CS50. 109 00:06:11,760 --> 00:06:19,542