1 00:00:00,000 --> 00:00:00,996 2 00:00:00,996 --> 00:00:12,470 >> [MUSIC PLAYING] 3 00:00:12,470 --> 00:00:13,210 >> ROB BOWDEN: Hi. 4 00:00:13,210 --> 00:00:16,870 I'm Rob and let's size up this problem. 5 00:00:16,870 --> 00:00:20,990 So we're going to start with copy.c as a template, but we're going to be 6 00:00:20,990 --> 00:00:23,340 making quite a few changes. 7 00:00:23,340 --> 00:00:27,570 >> Now we see we're immediately making a change where we're no longer checking 8 00:00:27,570 --> 00:00:31,560 for our rxc does not equal 3, but now we're checking rc does not equal 4. 9 00:00:31,560 --> 00:00:34,670 Since we also want to include, in addition to the in file and out files 10 00:00:34,670 --> 00:00:39,550 arguments, f which is going to be this factor by which we're scaling. 11 00:00:39,550 --> 00:00:45,430 >> So once we're sure of that, we want to use s scan f to convert the string 12 00:00:45,430 --> 00:00:49,030 argv1 to a float. 13 00:00:49,030 --> 00:00:51,330 And we're going to store that in factor. 14 00:00:51,330 --> 00:00:55,180 This additional character is making sure that we aren't actually entering 15 00:00:55,180 --> 00:00:59,200 something like 1.4 ABC at the command line. 16 00:00:59,200 --> 00:01:02,960 >> Now we're going to create some aliases since RV2 and RV3 aren't 17 00:01:02,960 --> 00:01:04,310 very helpful names. 18 00:01:04,310 --> 00:01:07,660 We're, instead, going to call them in file and out file. 19 00:01:07,660 --> 00:01:11,580 Now we're going to make sure that our factor was actually valid. 20 00:01:11,580 --> 00:01:16,330 So if factor is less than or equal to zero or greater than 100, then as per 21 00:01:16,330 --> 00:01:19,660 the spec, we should reject that factor. 22 00:01:19,660 --> 00:01:23,890 >> When we're sure it's good, now we can open the n file, and we have to make 23 00:01:23,890 --> 00:01:25,950 sure that it was successfully opened. 24 00:01:25,950 --> 00:01:28,630 If it didn't, that will return null. 25 00:01:28,630 --> 00:01:30,390 We're going to open the out file. 26 00:01:30,390 --> 00:01:33,420 And again, we want to check to make sure it's successfully opened. 27 00:01:33,420 --> 00:01:37,270 And if it didn't successfully open, then we also need to be sure to close 28 00:01:37,270 --> 00:01:40,870 the n file which originally successfully opened, or else we have a 29 00:01:40,870 --> 00:01:42,600 memory leak. 30 00:01:42,600 --> 00:01:46,350 >> So now we're going to read in the bitmap file header and bitmap info 31 00:01:46,350 --> 00:01:48,890 header from the n file. 32 00:01:48,890 --> 00:01:52,360 We're going to make sure that the n file was a valid bitmap. 33 00:01:52,360 --> 00:01:52,640 OK. 34 00:01:52,640 --> 00:01:55,100 >> So now we're going to start making some changes. 35 00:01:55,100 --> 00:01:58,840 So because we're going to be changing things, we first want to remember the 36 00:01:58,840 --> 00:02:01,510 old width of the n file. 37 00:02:01,510 --> 00:02:05,160 We want to remember the old padding of the n file using the same calculation 38 00:02:05,160 --> 00:02:06,990 from copy.c. 39 00:02:06,990 --> 00:02:09,840 >> And now we're going to change the bitmap info header. 40 00:02:09,840 --> 00:02:13,630 And so we're multiplying both the width and the height by factor since 41 00:02:13,630 --> 00:02:15,750 that's what we're scaling by. 42 00:02:15,750 --> 00:02:18,420 We're going to determine the new padding of the file by 43 00:02:18,420 --> 00:02:21,140 using the new width. 44 00:02:21,140 --> 00:02:27,330 And we're going to determine the new size of the image using the number of 45 00:02:27,330 --> 00:02:31,610 bytes in a single row which is going to be the number of pixels in that row 46 00:02:31,610 --> 00:02:35,960 times the size of a pixel plus the number of bytes of padding at the end 47 00:02:35,960 --> 00:02:40,310 of that row, and multiplying all that by the number of rows that we have. 48 00:02:40,310 --> 00:02:43,800 So that's the number of bytes we have in our image data. 49 00:02:43,800 --> 00:02:48,190 >> Bf.Bfsize now is going to be the number of bytes in our image beta plus 50 00:02:48,190 --> 00:02:49,350 the size of our headers. 51 00:02:49,350 --> 00:02:53,910 So plus size of bitmap file header and size of bitmap info header. 52 00:02:53,910 --> 00:02:54,510 OK. 53 00:02:54,510 --> 00:02:56,440 So that's it for our headers. 54 00:02:56,440 --> 00:02:59,030 We can write the file head and info header to our out 55 00:02:59,030 --> 00:03:01,590 file, and we're good. 56 00:03:01,590 --> 00:03:03,800 >> Now it's time to start actually writing the pixel 57 00:03:03,800 --> 00:03:05,120 data to the out file. 58 00:03:05,120 --> 00:03:10,460 We're going to declare a buffer of size old width RGB triples, and we're 59 00:03:10,460 --> 00:03:13,790 going to declare a variable called row numb, which is we're going to 60 00:03:13,790 --> 00:03:15,640 initially set equal to negative 1. 61 00:03:15,640 --> 00:03:19,090 We'll see that we're going to be using that in order to keep track of what 62 00:03:19,090 --> 00:03:22,640 row we currently have loaded into this buffer. 63 00:03:22,640 --> 00:03:23,290 OK. 64 00:03:23,290 --> 00:03:28,750 >> So now unlike the standard edition, instead of iterating over at the in 65 00:03:28,750 --> 00:03:32,900 file, we're going to iterate over each row in the out file and figure out 66 00:03:32,900 --> 00:03:38,130 which row in the in file we want to place in this row in the out file. 67 00:03:38,130 --> 00:03:44,930 So iterating over all rows in the out file using the new height, we're first 68 00:03:44,930 --> 00:03:48,890 going to determine the row in the old file we're going to use, which we're 69 00:03:48,890 --> 00:03:53,560 going to do by taking this current row divided by factor. 70 00:03:53,560 --> 00:03:58,000 So that's going to give us the row in the old file that we want. 71 00:03:58,000 --> 00:04:03,310 >> So now if row numb does not equal old y, we're going to have to read the row 72 00:04:03,310 --> 00:04:05,940 that we want into our cur row buffer. 73 00:04:05,940 --> 00:04:07,700 So how are we going to do that? 74 00:04:07,700 --> 00:04:11,650 First, we're going to figure out the position that begins that row in the 75 00:04:11,650 --> 00:04:13,100 original file. 76 00:04:13,100 --> 00:04:18,630 So that position is going to be past all of our headers and 77 00:04:18,630 --> 00:04:21,589 now past old y rows. 78 00:04:21,589 --> 00:04:23,880 >> And so how many bytes are in a single row? 79 00:04:23,880 --> 00:04:28,740 Again, size of RGB triple times old width plus old padding, so that's the 80 00:04:28,740 --> 00:04:30,640 number of bytes in a single row. 81 00:04:30,640 --> 00:04:33,680 And we want to skip past old y rows. 82 00:04:33,680 --> 00:04:37,580 So we're going to f seek and we're using seek set to start from the 83 00:04:37,580 --> 00:04:39,100 beginning of a file. 84 00:04:39,100 --> 00:04:42,740 We're going to f seek to this position in the file, putting us at the 85 00:04:42,740 --> 00:04:46,500 beginning of the row we want to read into our buffer. 86 00:04:46,500 --> 00:04:48,510 >> We're going to set row numb equal to old y. 87 00:04:48,510 --> 00:04:53,080 So now if we loop back and we want to use this same row in our out file, 88 00:04:53,080 --> 00:04:55,970 then we're not going to read it in again unnecessarily. 89 00:04:55,970 --> 00:04:59,310 So really, row numb is just an optimization. 90 00:04:59,310 --> 00:05:05,500 >> Finally, we're going to read into the current row the old width RGB triples 91 00:05:05,500 --> 00:05:08,040 that we want from the original file. 92 00:05:08,040 --> 00:05:12,270 So now cur row contains the pixels from the original file that we want to 93 00:05:12,270 --> 00:05:14,200 write into the out file. 94 00:05:14,200 --> 00:05:18,960 So now, just like above, instead of iterating over the old file, we need 95 00:05:18,960 --> 00:05:22,560 it to iterate over the new files rows. 96 00:05:22,560 --> 00:05:27,450 Well here, instead of iterating over all of the old pixels that in cur row, 97 00:05:27,450 --> 00:05:31,210 we want to iterate over all of the pixels in our new file in this 98 00:05:31,210 --> 00:05:32,480 particular row. 99 00:05:32,480 --> 00:05:34,140 >> Why do we want to do that? 100 00:05:34,140 --> 00:05:38,960 Because we see here that we're not actually necessarily using all of the 101 00:05:38,960 --> 00:05:41,020 pixels in the original file. 102 00:05:41,020 --> 00:05:46,630 Because if we're shrinking, we might actually want to skip the pixels. 103 00:05:46,630 --> 00:05:48,090 And we see that this-- 104 00:05:48,090 --> 00:05:49,690 x divided by factor-- 105 00:05:49,690 --> 00:05:55,620 closely mirrors up here where we say y divided by factor to figure out that 106 00:05:55,620 --> 00:06:02,480 the old y-th row corresponds to the y-th row in this new file. 107 00:06:02,480 --> 00:06:05,880 >> Now we're going to write all of these pixels from the old row 108 00:06:05,880 --> 00:06:07,440 into our new row. 109 00:06:07,440 --> 00:06:10,890 Once we've done that, we need to just put the padding at the end of our row 110 00:06:10,890 --> 00:06:15,540 and we'll loop back and continue for all of the rows in our new file. 111 00:06:15,540 --> 00:06:19,390 At the end, we need to close our old file, close our new file, and return 112 00:06:19,390 --> 00:06:21,540 zero because everything went fine. 113 00:06:21,540 --> 00:06:24,220 >> My name is Rob and this was Recess. 114 00:06:24,220 --> 00:06:29,184 >> [MUSIC PLAYING]