Intereting Posts

Извлечение jpeg-файлов из файла в C

Я пытаюсь извлечь файлы jpeg с карточки памяти как файл. Программа будет читать 512 байтовых блоков за раз, и если блок начинается с байт, идентифицирующих JPEG, моя программа должна записать в выходной файл эти байты. Он должен продолжать записывать эти байты, пока не найдет другую последовательность байтов, идентифицирующую JPEG, и в это время он должен прекратить запись в файл .jpg и записать на новый. Каждый файл должен быть назван 00x.jpg, где x является #.

Моя программа компилирует, но не создает все jpeg. Должно быть 16 JPEG, но это всего лишь 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; } 

    Я, возможно, пропущу что-то совершенно, но если все, что вы пытаетесь сделать, – это прочитать файл в блоках размером в 512 байт, проверив первые четыре октета каждого fragmentа для двух известных преамбул, а также, столкнувшись с ним, откройте файл изображения и запустите демпинг до следующего fragmentа, который соответствует закрытию файла и запускает новый, тогда около половины кода не требуется.

    Вы можете использовать значение image (null или нет), чтобы определить, открыт ли файл или нет. Кроме того, записывайте данные только в том случае, если файл открыт ( image != NULL) , и закрывайте существующий файл, если он открыт до перехода на следующий файл.

    Что-то вроде этого:

     #include  #include  #include  #include  int main(void) { // Prefixes of a jpeg file static const uint8_t jpeg1[4] = {0xff, 0xd8, 0xff, 0xe0}; static const uint8_t jpeg2[4] = {0xff, 0xd8, 0xff, 0xe1}; // open file for reading FILE* file = fopen("card.raw", "r"); // Open the file for reading if (file == NULL) { perror("card.raw"); return EXIT_FAILURE; } // target file FILE* image = NULL; // keep track of jpegs opened int pic = 0; // while there are bytes to be read in the file uint8_t buffer[512]; size_t n_bytes = 0; while( (n_bytes = fread(buffer,1, 512, file)) > sizeof(jpeg1)) { // compares first 4 bytes of buffer segment to jpeg prefixes to determine match if( memcmp(buffer, jpeg1, sizeof(jpeg1)) == 0 || memcmp(buffer, jpeg2, sizeof(jpeg2)) == 0) { // stores the jpeg file name with the # jpeg char jpegName[64]; sprintf(jpegName ,"00%d.jpg" , pic++); // match. close current file if present. if (image) fclose(image); // open new image file (sets NULL on failure) image = fopen(jpegName, "wb"); // write to target file image if (image == NULL) { perror(jpegName); break; } } // write whatever we have for our current bytes if (image) fwrite(buffer, n_bytes, 1, image); } // the above loop can exit with a file open (in fact, it is guaranteed // if we opened at least one file), so close it if one is active. if (image) fclose(image); } 

    Или что-то подобное. Это также открывает и закрывает файлы в двоичном режиме и не записывает посторонний мусор из последнего кадра, если он меньше 512 бит. Наконец, он увеличивает pic на каждый созданный файл и имеет (правда, мягкий) объем проверки ошибок.

    В любом случае, надеюсь, что это поможет. Удачи.