Reputation: 75
Update: Thanks for the help, I figured it out! I should have incremented i when I used
putc(input_char, output_file);
input_char = chars[i+1];
putc(input_char, output_file);
input_char = chars[i+2];
putc(input_char, output_file);
input_char = chars[i+3];
putc(input_char, output_file);
I have a file with several jpeg images. I need to put each image in a separate file. I've already put the file given into:
unsigned char* chars;
which I made equal to:
chars = (unsigned char*) malloc (sizeof(unsigned char)*count+1);
(count is the total number of bytes)
Here is a large portion of my code. I am trying to just get one image to work before I go through the entire file. I thought this would work, but I can't get an image. I get a file called image.jpg with a lot of bytes in it, but no picture. It seems like the very beginning of the file is what is wrong, but I'm not for sure about that. Any advice or tips would be appreciated. Thanks in advance.
FILE* output_file;
unsigned char input_char;
for(i=0; i <=count-3 && flag2==0; i++)
{
input_char = chars[i];
if ((chars[i] == 0xff ) &&
(chars[i+1] == 0xd8) &&
(chars[i+2] == 0xff) &&
(chars[i+3] == 0xe0))
{
if (flag==1) {
puts("closing file I");
fclose(output_file);
puts("closed I");
flag2 = 1;
break;
}
pictures++;
puts("New pic! I");
puts("Opening file I!");
output_file = fopen("image.jpg", "wb");
putc(input_char, output_file);
input_char = chars[i+1];
putc(input_char, output_file);
input_char = chars[i+2];
putc(input_char, output_file);
input_char = chars[i+3];
putc(input_char, output_file);
flag = 1;//there is at least one image, so it will need to be closed
}
else if ((chars[i] == 0xff) &&
(chars[i+1] == 0xd8) &&
(chars[i+2] == 0xff) &&
(chars[i+3] == 0xe1))
{
if (flag==1) {
puts("closing file II");
fclose(output_file);
puts("closed II");
flag2 = 1;
break;
}
pictures++;
puts("New pic II!");
puts("Opening file! II");
output_file = fopen("Image.jpg", "wb");
putc(input_char, output_file);
input_char = chars[i+1];
putc(input_char, output_file);
input_char = chars[i+2];
putc(input_char, output_file);
input_char = chars[i+3];
putc(input_char, output_file);
flag = 1;//there is at least one image, so it will need to be closed
}
else
{
if (flag==1) //There is an image opened
{
putc(input_char, output_file);
}
}
}
Upvotes: 3
Views: 1094
Reputation: 104020
First things first, I think you'd have more success with a complete re-write using the memmem(3)
function (memmem(3)
is a GNU extension like strstr(3)
, but for arbitrary memory, not just C-strings. It wouldn't be difficult to write your own version if memmem(3)
isn't already available to you.). Of course, using memmem(3)
would still be a problem if the embedded JPEG file included data that matched these header bytes. I don't know that it is possible, but I also don't know that it is impossible. Be careful. :)
This loop looks like nothing but trouble to maintain over time, which is why I suggested a completely different approach. But if you're committed to this approach, note that you'll be copying your header bytes several times; I expect the first few bytes of your output file will actually be: 0xff 0xd8 0xff 0xe0 0xd8 0xff 0xe0
-- you haven't stepped i
forward to account for all the written characters in your loop.
I think your code would be easier to read and maintain if you replace this code:
putc(input_char, output_file); input_char = chars[i+1]; putc(input_char, output_file); input_char = chars[i+2]; putc(input_char, output_file); input_char = chars[i+3]; putc(input_char, output_file);
with this code:
putc(chars[i++], output_file);
putc(chars[i++], output_file);
putc(chars[i++], output_file);
putc(chars[i++], output_file);
(The i++
is the bugfix, in that you're not moving i
forward for each character; removing the input_char
variable is just cleanup, as I found it more difficult to read with the variable than without it.)
Upvotes: 1