>> [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]