Я пытаюсь извлечь jpeg-файлы из файла с карточкой памяти. Программа будет читать 512 байтовых блоков за раз, и если блок начинается с байт, идентифицирующих JPEG, моя программа должна записать в выходной файл эти байты. Он должен продолжать записывать эти байты, пока не найдет другую последовательность байтов, идентифицирующую JPEG, и в это время он должен прекратить запись в файл .jpg и записать на новый. Каждый файл должен быть назван 00x.jpg, где x является #.Извлечение jpeg-файлов из файла в C
Моя программа скомпилирует, но не производит все jpeg. Там должно быть 16 JPEGs, но она производит только 7.
int main(void)
{
// open file for reading
FILE* file = fopen("card.raw", "r"); // Open the file for reading
// target file
FILE* image;
// buffer of bytes
uint8_t buffer[512];
// check for NULL file
if (file == NULL)
{
fclose(file);
printf("Could not open file");
return 1;
}
// Prefixes of a jpeg file
uint8_t jpeg1[4] = {0xff, 0xd8, 0xff, 0xe0};
uint8_t jpeg2[4] = {0xff, 0xd8, 0xff, 0xe1};
// keep track of jpegs opened
int pic = 0;
int match = 0;
// is file open?
int open = 0;
// stores first 4 bytes of block
uint8_t check[4];
int byteNum;
byteNum = fread(buffer, 512, 1, file);
// while there are bytes to be read in the file
while(fread(buffer,512, 1, file) > 0)
{
for (int x=0; x < 4; x++)
{
check[x] = buffer[x];
}
// compares first 4 bytes of buffer segment to jpeg prefixes to determine match
if((memcmp(check, jpeg1,4) == 0) || (memcmp(check, jpeg2, 4) == 0))
{
match = 1;
}
// if encounter a jpeg and file is open, close the file and set match to false
if (match == 1 && open == 1)
{
fclose(image);
open = 0;
match = 0;
}
// if match is true and file is closed, create jpeg output file, increment pic#, set file to open, set match to false, open target file
if (match == 1 && open == 0)
{
// stores name of jpegfile
char jpegName[8];
// stores the jpeg file name with the # jpeg
sprintf(jpegName ,"%03d.jpg" ,pic);
pic++;
open = 1; // signifies target jpeg file is open
match = 0; // sets match back to 0 (false) so it can detect the next match to signify closing the writing
image=fopen(jpegName, "w"); // write to target file image
}
// if file target is still open but no match, then keep writing since you're in the middle of a jpeg
if (match == 0 && open == 1)
{
fwrite(buffer, 512, 1, image);
}
}
fclose(file);
return 0;
}
Fyi, если вы когда-либо начинаете писать, вы пишете первые 512 байт каждого файла * дважды *. Сначала, когда 'match == 1 && open == 0', где вы устанавливаете' open = 1; ', откройте файл, запишите данные и установите' match = 0; ', затем сразу же после проверки' match = = 0 && open == 1) ', что будет, потому что вы просто установите его таким образом, чтобы снова написать тот же блок. Первый 'fwrite', похоже, не должен быть там. – WhozCraig
Вы правы. Я удалил это. Все еще не выводит jpg. –
О, это не единственная проблема, только я заметил. Для проверки всех допущений, которые вы делаете, нужно пройти через отладчик. Пример: вы никогда не увеличиваете 'pic', поэтому вы всегда пишете одно имя целевого файла' 000.jpg'. – WhozCraig