I got a segmentation fault with this code. Can anyone help? I have tried a couple of ways but still could not solve the problem. I tried replacing FILE *img = NULL by FILE *img, but it gives another error said variable 'img' is uninitialized when used in fwrite(buffer, 512, 1, img)
#include <stdio.h>
#include <cs50.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
//Open memory card
if (argc != 2)
{
printf("Usage: ./recover image\n");
return 1;
}
FILE *file = fopen(argv[1], "r");
if (!file)
{
return 1;
}
//Read 512 bytes into a buffer
int counter = 0;
unsigned char buffer[512];
char filename[8];
FILE *img = NULL;
while (fread(buffer, 512, 1, file) == 1)
{
if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] && 0xf0 == 0xe0))
{
//If first JPEG
if (counter == 0)
{
//open a new file
sprintf(filename, "%03i.jpg", counter);
img = fopen(filename, "w");
//write the array into the new file
fwrite(buffer, 512, 1, img);
counter++;
}
//if not first JPEG
else
{
//close the file
fclose(img);
//open a new file
sprintf(filename, "%03i.jpg", counter);
img = fopen(filename, "w");
//write the array into the new file
fwrite(buffer, 512, 1, img);
counter++;
}
}
//Else, if already found new JPEG
else
{
fwrite(buffer, 512, 1, img);
}
}
//Close any remaining files
fclose(img);
fclose(file);
return 0;
}
When this if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] && 0xf0 == 0xe0)) is not true (as with the first read), what does program do?
This comment //Else, if already found new JPEG needs to be put into code; ie the following write needs to be conditional.
Related
This program is designed to recover images from a digital camera SD card. The program is not passing the last three checks when I run it through check50. The program does not recover 000.jpg, middle image, and image 049.jpg. The error message indicated the program timed out while waiting for program to exit. The debugging tool has not been able to help me with this. Thank you for your help.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
// Buffer to store card data
// recover deleter images
int main(int argc, char *argv[])
{
// count is 2
if(argc < 2)
{
printf("usage: ./recover image.raw\n");
return 1;
}
// Read file
char *file = argv[1];
FILE *card = fopen(file, "r");
unsigned char* buffer = malloc(512);
// Check that file is valid
if (fopen(file, "r") == NULL)
{
printf("could not open %s.\n", file);
return 1;
}
char* filename = malloc(3 * sizeof(int));
//JPGs created
int img_count = 0;
int test_counter = 0;
FILE *img nodd= NULL;
// Read 512 chars
while (test_counter == 0)
{
fread(buffer, sizeof(char), 512, card);
// Detect JPEG
if(buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && buffer[3] && 0xf0 == 0xe0)
{
// Write JPEG
sprintf(filename, "%0x3i.jpg", img_count);
img = fopen(filename, "w");
img_count++;
while (true)
{
fread(buffer, sizeof(char), 512, card);
if(buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && buffer[3] && 0xf0 == 0xe0)
{
sprintf(filename, "%0x3i.jpg", img_count);
img = fopen(filename, "a");
img_count++;
test_counter++;
fwrite(buffer, sizeof(char), 512, img);
break;
}
else
{
fwrite(buffer, sizeof(char), 512, img);
break;
}
}
while (fread(buffer, sizeof(char), 512, card)!= 0)
if(buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && buffer[3] && 0xf0 == 0xe0)
{
// Pointer for JPG created
fclose(img);
sprintf(filename, "%0x3i.jpg", img_count);
img = fopen(filename, "a");
img_count++;
}
fwrite(buffer, sizeof(char), 512, img);
}
}
free(buffer);
fclose(img);
return 0;
}
So I'm trying CS50 Recover exercise (where you need to search for jpg files in a memory card and whenever you find one- you open a new file and write the jpg found to the new file). My code compiles and returns 51 jpegs instead of only 50 and all of them are incorrect. Please, I need some cues on what to focus at and fix/replace.
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
typedef uint8_t BYTE;
int main(int argc, char *argv[])
{
// Check for valid usage
if ( argc != 2)
{
printf("Usage: ./recover IMAGE\n");
return 1;
}
// Check for valid image
FILE *image = fopen(argv[1], "r");
if (image == NULL)
{
return 1;
}
BYTE buffer[512];
int i = 0;
char new_image[8];
FILE *output;
FILE *output1;
while (fread (buffer, 1, 512, image) == 512)
{
// IF Start of a JPEG
if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && ((buffer[3] & 0xf0) == 0xe0))
{
sprintf(new_image, "%03i.jpg", i);
//if first JPEG
if ( i == 0)
{
output = fopen(new_image, "w");
fwrite(buffer, 512, 1, output);
i++;
}
// if not first JPEG
else
{
fclose(output);
sprintf(new_image, "%03i.jpg", i);
output1 = fopen(new_image, "w");
fwrite(buffer, 1, 512, output1);
fclose(output1);
i++;
}
}
// if not start of a JPEG
else
{
output = output1 = fopen(new_image, "w");
fwrite(buffer, 1, 512, output);
}
}
fclose(image);
}
I'm trying to solve this problem which consists of reading data from a "memory card" and write it into new readable jpg files.
I'm getting 50 files named correctly as far as I can tell but their data is incorrect. to me it looks like it should be writing into each jpg the data read into the buffer from the card or argv[1] but I'm guessing I'm missing something and I can't figure out what.
this is what I wrote so far:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
typedef uint8_t BYTE;
int is_jpg(BYTE(buffer[]))
{
if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xe0) == 0xe0)
{
return 1;
}
else
{
return 0;
}
}
int main(int argc, char *argv[])
{
BYTE buffer[512];
//checks argument validity
if (argc != 2)
{
printf("Usage: ./recover image\n");
return 1;
}
FILE *file = fopen(argv[1], "r");
//printf("continuing program\n");
//checks if the file exists
if (file == NULL)
{
printf("No file found\n");
return 2;
}
int file_count = 0;
char file_name[8];
//sprintf(file_name, "%03d.jpg", file_count);
FILE *image;
while (fread(buffer, 512, 1, file) == 1)
{
if (is_jpg(buffer) == 1)
{
if (file_count != 0)
{
fclose(image);
}
sprintf(file_name, "%03d.jpg", file_count);
image = fopen(file_name, "w");
fread(&buffer, 512, 1 , file);
fwrite(&buffer, 512, 1, image);
file_count++;
}
else if (file_count > 0)
{
fwrite(buffer, 512, 1, image);
}
//fwrite(&buffer, 512, 1, image);
}
}
When you detect the header, you do an extra fread [after the image = fopen(file_name, "w"); call].
You want to write the header to the output file/stream. But, the extra fread trashes the header data and the first block of the file is data and not the header as you desire.
You only want the fread at the top of the loop.
I am having trouble identifying why I am getting blank images when recovering jps for an assignment in CS50. I read the entire file, write whenever the start of a jpg file is found, and close whenever the end of a jpg file is found. I create the total of 50 images, but all of them are blank. Could someone help push me in the right direction?
This is my code:
const int BLOCK = 512;
uint8_t buffer[BLOCK];
char filename[50][8] = { };
int counter = 0;
while (fread(buffer, BLOCK, 1, input) == 1)
{
sprintf(&filename[counter][0], "%03i.jpg", counter);
FILE *img = fopen(&filename[counter][0], "w");
if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer [2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
{
if ((buffer[511] & 0xf0) != 0xe0)
{
fwrite(buffer, BLOCK, 1, img);
counter++;
}
else
{
fclose(img);
}
}
}
I made the update here:
while (fread(buffer, BLOCK, 1, input) == 1)
{
sprintf(filename, "%03i.jpg", counter);
FILE *img = fopen(filename, "w");
if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer [2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
{
if ((buffer[511] & 0xf0) != 0xe0)
{
fwrite(buffer, BLOCK, 1, img);
}
else
{
fclose(img);
counter++;
}
}
}
This question is now solved. My whole logic was flawed and I wasnt writing anything, I was just opening files. Bellow is my reworked code, its funny how overnight everything just clicked and was able to write it in like 10 minutes!
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
const int BLOCK = 512;
int main(int argc, char *argv[])
{
if (argc != 2)
{
printf("Usage: ./recover card.raw\n");
return 1;
}
FILE *input = fopen(argv[1], "r");
if (input == NULL)
{
printf("Could not open file.\n");
return 1;
}
uint8_t buffer[BLOCK];
char filename[8] = { };
int counter = 0;
FILE *img;
while (fread(buffer, BLOCK, 1, input) == 1)
{
if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer [2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
{
sprintf(filename, "%03i.jpg", counter);
img = fopen(filename, "w");
if (counter == 0)
{
fwrite(buffer, BLOCK, 1, img);
counter++;
}
else
{
fclose(img);
img = fopen(filename, "w");
fwrite(buffer, BLOCK, 1, img);
counter++;
}
}
else if (counter != 0)
{
fwrite(buffer, BLOCK, 1, img);
}
}
fclose(input);
fclose(img);
}
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
int main(int argc, char *argv[])
{
// open memory card
if(argc > 2 )
{
printf("Usage: ./recover image");
return 1;
}
FILE *file = fopen(argv[1], "r");
FILE *img;
// repeat until end
int i = 0;
// 512 bytes into buffer
uint8_t buffer[2048];
char *filename = malloc(8);
// if start of new jpeg
while(fread(&buffer, 512, 4, file)) // read card
{
if(buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0) // if start new jpeg
{
// if first
i++;
sprintf(filename, "%03i.jpg", i);
img = fopen(filename, "w");
fwrite(&buffer, sizeof(uint8_t), 1, img); // fixed
}
//else
else
{
// if still reading jpeg
if(img != NULL)
{
fwrite(&buffer, sizeof(uint8_t), 1, img);
}
}
}
//close
free(filename);
fclose(file);
return 0;
}
I think my code is pretty close to being done but the images returned are invalid or unsupported image format. It compiles fine and it returns 12 images. I do not want to look at a solution to fix this. Where did my code mess up?