1 00:00:00,000 --> 00:00:00,494 2 00:00:00,494 --> 00:00:13,350 >> [MUSIC PLAYING] 3 00:00:13,350 --> 00:00:14,080 >> ROB BOWDEN: Hi. 4 00:00:14,080 --> 00:00:17,550 I'm Rob, and let's hope that this solution helps put you 5 00:00:17,550 --> 00:00:19,600 on the road to recovery. 6 00:00:19,600 --> 00:00:22,700 So let's get started. 7 00:00:22,700 --> 00:00:25,660 >> We see that immediately we're just to make sure that we're 8 00:00:25,660 --> 00:00:27,170 using Recover correctly. 9 00:00:27,170 --> 00:00:31,490 So the usage should just be something like dot slash recover. 10 00:00:31,490 --> 00:00:35,500 >> Now we're going to open the expected card dot raw file. 11 00:00:35,500 --> 00:00:39,740 We see here that we're using the constant raw underscore file name, 12 00:00:39,740 --> 00:00:44,200 which up here we have hash defined as card dot raw. 13 00:00:44,200 --> 00:00:45,030 OK. 14 00:00:45,030 --> 00:00:48,210 >> So we need to make sure that that successfully opened because if it 15 00:00:48,210 --> 00:00:51,150 didn't, then we should warn the user. 16 00:00:51,150 --> 00:00:56,770 But assuming that it did, we're now going to declare a buffer of size JPEG 17 00:00:56,770 --> 00:00:58,170 file name length. 18 00:00:58,170 --> 00:01:02,060 So this is going to be the buffer that we're going to sprintf into. 19 00:01:02,060 --> 00:01:04,360 >> So what is JPEG file name length? 20 00:01:04,360 --> 00:01:08,490 Up here, we see that it's hash defined as eight. 21 00:01:08,490 --> 00:01:10,670 So why eight? 22 00:01:10,670 --> 00:01:15,150 Well a given file will be named something like zero zero zero. 23 00:01:15,150 --> 00:01:19,460 JPG and then we need a backslash zero. 24 00:01:19,460 --> 00:01:22,720 So we need a buffer that can store eight characters. 25 00:01:22,720 --> 00:01:25,190 Now we're going to have a counter that's going to keep track of the 26 00:01:25,190 --> 00:01:27,780 number JPEGs we found. 27 00:01:27,780 --> 00:01:31,590 >> And finally, we're going to have a JPEG file which is initially null 28 00:01:31,590 --> 00:01:35,920 which is going to be the currently open file that we're writing to. 29 00:01:35,920 --> 00:01:37,540 Now we're going to have an additional buffer. 30 00:01:37,540 --> 00:01:41,350 This is not the same as our sprintf buffer where this buffer is the one 31 00:01:41,350 --> 00:01:45,020 that we're reading in the data from the card dot raw. 32 00:01:45,020 --> 00:01:48,900 >> So the buffer is going to be of unsigned chars, which you can 33 00:01:48,900 --> 00:01:53,560 basically just treat us bytes, and it's going to be of size block size 34 00:01:53,560 --> 00:01:57,950 where, as we tell you, block size is 512. 35 00:01:57,950 --> 00:02:03,070 So JPEGs you can treat everything as blocks of 512 bytes. 36 00:02:03,070 --> 00:02:05,890 >> Now we're going to loop over the entire file. 37 00:02:05,890 --> 00:02:12,980 We're going to f read into our buffer a single byte block size times from 38 00:02:12,980 --> 00:02:14,710 the card dot raw file. 39 00:02:14,710 --> 00:02:16,630 Now what does f read return? 40 00:02:16,630 --> 00:02:20,050 It returns the number of items that it successfully read. 41 00:02:20,050 --> 00:02:27,310 So if it managed to read 512 bytes, then we want to see whether this was a 42 00:02:27,310 --> 00:02:29,700 JPEG or write it to a JPEG file. 43 00:02:29,700 --> 00:02:34,450 And if it did not return 512 bytes, then either the file has ended in 44 00:02:34,450 --> 00:02:37,870 which case we'll break out of the y loop, or there are some sort of error 45 00:02:37,870 --> 00:02:40,300 in which case we'll also break out of the y loop, but we'll want to report 46 00:02:40,300 --> 00:02:41,990 that something went wrong. 47 00:02:41,990 --> 00:02:42,290 >> OK. 48 00:02:42,290 --> 00:02:47,630 So assuming that we successfully read in 512 bytes, we want to first check 49 00:02:47,630 --> 00:02:53,070 to make that these bytes that we just read in begin a JPEG. 50 00:02:53,070 --> 00:02:56,430 So if is JPEG header of our buffer. 51 00:02:56,430 --> 00:02:58,460 Now what it is JPEG header doing? 52 00:02:58,460 --> 00:03:00,120 Let's look. 53 00:03:00,120 --> 00:03:05,270 >> Up here, we see that this function is returning a bull, and that bull-- 54 00:03:05,270 --> 00:03:08,820 well here, we're checking to see if header zero equals this constant and 55 00:03:08,820 --> 00:03:11,880 header one equals this constant and header two equals this constant, 56 00:03:11,880 --> 00:03:15,640 header three equals this or this constant where all these constants are 57 00:03:15,640 --> 00:03:20,340 just hash defined right here and are exactly what we told you in the spec 58 00:03:20,340 --> 00:03:22,700 that a JPEG begins with. 59 00:03:22,700 --> 00:03:27,300 And so this function is just going to return true if this buffer represents 60 00:03:27,300 --> 00:03:31,750 the start of a new JPEG and false otherwise. 61 00:03:31,750 --> 00:03:32,520 >> OK. 62 00:03:32,520 --> 00:03:38,490 So if this does represent a new JPEG, then we first want to check to see if 63 00:03:38,490 --> 00:03:42,030 JPEG file is not equal to null, in which case we close it. 64 00:03:42,030 --> 00:03:44,940 And so why do we need to check to see if it's not null? 65 00:03:44,940 --> 00:03:48,980 Well the very first JPEG that we find we will not already have 66 00:03:48,980 --> 00:03:50,440 an open JPEG file. 67 00:03:50,440 --> 00:03:55,580 And so, if we try to close that, then we're not doing something quite right. 68 00:03:55,580 --> 00:03:59,090 >> But every subsequent JPEG that we open, we want to close 69 00:03:59,090 --> 00:04:00,710 the previous file. 70 00:04:00,710 --> 00:04:04,630 So now we're going to use sprintf as we said before where we're using the 71 00:04:04,630 --> 00:04:06,280 buffer JPEG file name. 72 00:04:06,280 --> 00:04:09,870 And we're going to use JPEG file name format as our format. 73 00:04:09,870 --> 00:04:12,030 And what is that? 74 00:04:12,030 --> 00:04:18,450 Up here, we see that it is percent zero 3D.JPEG where the zero three just 75 00:04:18,450 --> 00:04:22,089 says that we'll use three integers for this padded with zeros. 76 00:04:22,089 --> 00:04:27,470 So this is how we'll get zero zero one.JPEG and zero 10.JPEG and so on. 77 00:04:27,470 --> 00:04:29,060 >> We're going to use sprintf. 78 00:04:29,060 --> 00:04:33,760 And the integer that we're inserting into the string is numb JPEGs 79 00:04:33,760 --> 00:04:36,380 recovered, which is originally zero. 80 00:04:36,380 --> 00:04:39,950 So the first file opened is going to be zero zero zero dot JPEG. 81 00:04:39,950 --> 00:04:43,330 And then we're incrementing it so the next file we open will be zero zero 82 00:04:43,330 --> 00:04:46,830 one dot JPEG and we'll increment it again so it'll be zero zero two dot 83 00:04:46,830 --> 00:04:49,100 JPEG and so on. 84 00:04:49,100 --> 00:04:49,850 >> All right. 85 00:04:49,850 --> 00:04:53,210 So now the inside of JPEG file name, we have the name of the 86 00:04:53,210 --> 00:04:54,990 file that we want. 87 00:04:54,990 --> 00:04:58,640 We can f open that file for writing. 88 00:04:58,640 --> 00:04:59,170 OK. 89 00:04:59,170 --> 00:05:02,820 And once again, we need to check to make sure that the file successfully 90 00:05:02,820 --> 00:05:08,460 opened since if it didn't, then there was some error. 91 00:05:08,460 --> 00:05:13,100 >> So now we've gotten past the is this a JPEG part. 92 00:05:13,100 --> 00:05:16,390 And here, we see we're going to write to the JPEG. 93 00:05:16,390 --> 00:05:20,980 But we first have this check which says if JPEG file does not equal null. 94 00:05:20,980 --> 00:05:22,490 Why do we need that? 95 00:05:22,490 --> 00:05:28,020 Well JPEG file equals null when we currently have an open JPEG. 96 00:05:28,020 --> 00:05:31,870 >> What if card dot raw starts with a bunch of bytes that 97 00:05:31,870 --> 00:05:33,510 don't represent a JPEG? 98 00:05:33,510 --> 00:05:36,240 Then we're going to want to skip over those bytes. 99 00:05:36,240 --> 00:05:39,600 If we don't have this check, then we're going to write to an unopened 100 00:05:39,600 --> 00:05:45,540 file the first 512 bytes of the card which isn't good. 101 00:05:45,540 --> 00:05:46,030 OK. 102 00:05:46,030 --> 00:05:51,330 >> So assuming we have an open file, then we're going to write to that file the 103 00:05:51,330 --> 00:05:53,290 512 bytes that we have in our buffer. 104 00:05:53,290 --> 00:05:57,390 And we're once again checking to make sure that the 512 bytes successfully 105 00:05:57,390 --> 00:06:01,140 were written because if they were not successfully written, then something 106 00:06:01,140 --> 00:06:02,080 went wrong. 107 00:06:02,080 --> 00:06:06,540 We'll close our files, print that something went wrong, and return. 108 00:06:06,540 --> 00:06:10,940 Assuming everything goes correctly, then we'll keep looping closing the 109 00:06:10,940 --> 00:06:15,060 old file, opening the new file, writing data to the new file, and so 110 00:06:15,060 --> 00:06:20,990 on until finally, this f read returns zero which means 111 00:06:20,990 --> 00:06:23,280 that the file is done. 112 00:06:23,280 --> 00:06:28,490 >> So now that the card reading is over, we see that we're going to f close the 113 00:06:28,490 --> 00:06:33,250 last file that we had open, but we're checking if JPEG file 114 00:06:33,250 --> 00:06:34,900 does not equal null. 115 00:06:34,900 --> 00:06:39,520 Well the f close makes sense because as we're opening files, we're closing 116 00:06:39,520 --> 00:06:43,870 the previous file, but the very last file that we opened never gets closed. 117 00:06:43,870 --> 00:06:45,580 So that's what this is doing. 118 00:06:45,580 --> 00:06:47,720 >> But why we need to check for null? 119 00:06:47,720 --> 00:06:53,130 Well what if card dot raw did not have a single JPEG inside of it? 120 00:06:53,130 --> 00:06:56,640 In that case, we would have never opened a file. 121 00:06:56,640 --> 00:07:00,230 And if we never open a file, we should not try to close that file. 122 00:07:00,230 --> 00:07:03,000 So that's what this check is doing. 123 00:07:03,000 --> 00:07:07,880 >> Now here, as I said before, we could have broken out that y loop either if 124 00:07:07,880 --> 00:07:13,520 the card has ended or if there are some error reading from the card. 125 00:07:13,520 --> 00:07:16,680 So this is checking to see if there was an error reading from the card, in 126 00:07:16,680 --> 00:07:19,400 which case, we'll say there was an error reading. 127 00:07:19,400 --> 00:07:22,130 We don't want the user to think everything went successfully. 128 00:07:22,130 --> 00:07:24,750 And we'll return one for error. 129 00:07:24,750 --> 00:07:29,580 >> Finally, we'll f close our raw file, our card dot raw, to indicate that 130 00:07:29,580 --> 00:07:34,070 everything went well and return zero and that's it. 131 00:07:34,070 --> 00:07:36,130 >> My name is Rob and this was Recover. 132 00:07:36,130 --> 00:07:42,102 >> [MUSIC PLAYING]