[MUSIC PLAYING] ROB BOWDEN: Hi. I'm Rob, and let's hope that this solution helps put you on the road to recovery. So let's get started. We see that immediately we're just to make sure that we're using Recover correctly. So the usage should just be something like dot slash recover. Now we're going to open the expected card dot raw file. We see here that we're using the constant raw underscore file name, which up here we have hash defined as card dot raw. OK. So we need to make sure that that successfully opened because if it didn't, then we should warn the user. But assuming that it did, we're now going to declare a buffer of size JPEG file name length. So this is going to be the buffer that we're going to sprintf into. So what is JPEG file name length? Up here, we see that it's hash defined as eight. So why eight? Well a given file will be named something like zero zero zero. JPG and then we need a backslash zero. So we need a buffer that can store eight characters. Now we're going to have a counter that's going to keep track of the number JPEGs we found. And finally, we're going to have a JPEG file which is initially null which is going to be the currently open file that we're writing to. Now we're going to have an additional buffer. This is not the same as our sprintf buffer where this buffer is the one that we're reading in the data from the card dot raw. So the buffer is going to be of unsigned chars, which you can basically just treat us bytes, and it's going to be of size block size where, as we tell you, block size is 512. So JPEGs you can treat everything as blocks of 512 bytes. Now we're going to loop over the entire file. We're going to f read into our buffer a single byte block size times from the card dot raw file. Now what does f read return? It returns the number of items that it successfully read. So if it managed to read 512 bytes, then we want to see whether this was a JPEG or write it to a JPEG file. And if it did not return 512 bytes, then either the file has ended in which case we'll break out of the y loop, or there are some sort of error in which case we'll also break out of the y loop, but we'll want to report that something went wrong. OK. So assuming that we successfully read in 512 bytes, we want to first check to make that these bytes that we just read in begin a JPEG. So if is JPEG header of our buffer. Now what it is JPEG header doing? Let's look. Up here, we see that this function is returning a bull, and that bull-- well here, we're checking to see if header zero equals this constant and header one equals this constant and header two equals this constant, header three equals this or this constant where all these constants are just hash defined right here and are exactly what we told you in the spec that a JPEG begins with. And so this function is just going to return true if this buffer represents the start of a new JPEG and false otherwise. OK. So if this does represent a new JPEG, then we first want to check to see if JPEG file is not equal to null, in which case we close it. And so why do we need to check to see if it's not null? Well the very first JPEG that we find we will not already have an open JPEG file. And so, if we try to close that, then we're not doing something quite right. But every subsequent JPEG that we open, we want to close the previous file. So now we're going to use sprintf as we said before where we're using the buffer JPEG file name. And we're going to use JPEG file name format as our format. And what is that? Up here, we see that it is percent zero 3D.JPEG where the zero three just says that we'll use three integers for this padded with zeros. So this is how we'll get zero zero one.JPEG and zero 10.JPEG and so on. We're going to use sprintf. And the integer that we're inserting into the string is numb JPEGs recovered, which is originally zero. So the first file opened is going to be zero zero zero dot JPEG. And then we're incrementing it so the next file we open will be zero zero one dot JPEG and we'll increment it again so it'll be zero zero two dot JPEG and so on. All right. So now the inside of JPEG file name, we have the name of the file that we want. We can f open that file for writing. OK. And once again, we need to check to make sure that the file successfully opened since if it didn't, then there was some error. So now we've gotten past the is this a JPEG part. And here, we see we're going to write to the JPEG. But we first have this check which says if JPEG file does not equal null. Why do we need that? Well JPEG file equals null when we currently have an open JPEG. What if card dot raw starts with a bunch of bytes that don't represent a JPEG? Then we're going to want to skip over those bytes. If we don't have this check, then we're going to write to an unopened file the first 512 bytes of the card which isn't good. OK. So assuming we have an open file, then we're going to write to that file the 512 bytes that we have in our buffer. And we're once again checking to make sure that the 512 bytes successfully were written because if they were not successfully written, then something went wrong. We'll close our files, print that something went wrong, and return. Assuming everything goes correctly, then we'll keep looping closing the old file, opening the new file, writing data to the new file, and so on until finally, this f read returns zero which means that the file is done. So now that the card reading is over, we see that we're going to f close the last file that we had open, but we're checking if JPEG file does not equal null. Well the f close makes sense because as we're opening files, we're closing the previous file, but the very last file that we opened never gets closed. So that's what this is doing. But why we need to check for null? Well what if card dot raw did not have a single JPEG inside of it? In that case, we would have never opened a file. And if we never open a file, we should not try to close that file. So that's what this check is doing. Now here, as I said before, we could have broken out that y loop either if the card has ended or if there are some error reading from the card. So this is checking to see if there was an error reading from the card, in which case, we'll say there was an error reading. We don't want the user to think everything went successfully. And we'll return one for error. Finally, we'll f close our raw file, our card dot raw, to indicate that everything went well and return zero and that's it. My name is Rob and this was Recover. [MUSIC PLAYING]