2015-07-30 3 views
2

Я пытаюсь извлечь 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; 
} 
+0

Fyi, если вы когда-либо начинаете писать, вы пишете первые 512 байт каждого файла * дважды *. Сначала, когда 'match == 1 && open == 0', где вы устанавливаете' open = 1; ', откройте файл, запишите данные и установите' match = 0; ', затем сразу же после проверки' match = = 0 && open == 1) ', что будет, потому что вы просто установите его таким образом, чтобы снова написать тот же блок. Первый 'fwrite', похоже, не должен быть там. – WhozCraig

+0

Вы правы. Я удалил это. Все еще не выводит jpg. –

+2

О, это не единственная проблема, только я заметил. Для проверки всех допущений, которые вы делаете, нужно пройти через отладчик. Пример: вы никогда не увеличиваете 'pic', поэтому вы всегда пишете одно имя целевого файла' 000.jpg'. – WhozCraig

ответ

1

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

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

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

#include <stdio.h> 
#include <stdlib.h> 
#include <stdint.h> 
#include <string.h> 

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 на каждый созданный файл и имеет (правда, мягкий) объем ошибок.

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

Смежные вопросы