2016-09-06 2 views
-1

Ну, в основном я написал эту программу для своего курса компьютера (крик CS50), который восстанавливает изображения из файла .raw. Мне удалось восстановить программу из 50 файлов в этом файле.У программы восстановления изображений есть проблема

Проблема im, имеющая прямо сейчас с программой, заключается в том, что программа не может восстановить как первый, так и второй файл, расположенный на .raw. Он либо читает, либо записывает самый первый файл (эта девушка на снежном фоне) или второй файл на .raw (парень за книгами).

По какой-то причине, если я изменю fopen из записи в append, я могу переключаться между фотографией девушки и парня, но я не могу открыть оба.

https://github.com/CoreData/cs50/blob/master/pset4/jpg/card.raw Это ссылка на card.raw, к сожалению, его не то же самое, что один Im помощью, но даже используя этот вы получите два различных изображения для image1.jpg в зависимости от того, были ли вы FOPEN с «а» или «ш».

Любые идеи ???

если вы, ребята, хотите какой-либо дополнительная информация, просто дайте мне знать

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

#include "bmp2.h" 

int main(void) 
{ 
    /*OPEN CARD FILE*/ 
    char* infile = "card.raw";; 

    FILE* card = fopen(infile, "r"); 
    if (card == NULL) 
    { 
     printf("Could not open %s.\n", "card.raw"); 
     return 2; 
    } 

    int f = 0, c = 0, l = 0, x = 128, imageno = 1; 
    // c signals that a jpg is being written 
    // l size control, 0 means 0 jpgs 
    FILE* images; 
    char* title = (char*)malloc(15); 

    /*repeat until end of card*/ 
    do 
    { 
     //read one block into buffer 
     INTROJPG *buffer = (INTROJPG*)malloc(sizeof(INTROJPG)*x); 

     for (int i = 0; i < 128; i++) 
     { 
      fread(&buffer[i], sizeof(INTROJPG), 1, card); 
     } 

     if (buffer[0].first == 0xff && buffer[0].second == 0xd8 && buffer[0].third == 0xff) 
     { 
      sprintf(title, "image%d.jpg", imageno); //change jpg title 

      if (f == 1) //close previous jpg 
      { 
       fclose(images); 
       imageno++; 
      } 

      images = fopen(title, "w"); 
      f = 1; //very first jpg has been opened 
      c = 1; //jpg open 
      l++; //jpg count + 1 
     } 

     //jpg already open? 
     if (c == 1) 
     { 
      for (int i = 0; i < 128; i++) 
      { 
       fwrite(&buffer[i], sizeof(INTROJPG), 1, images); 
      } 
     } 
     free(buffer); 
    }  
    while (l < 50); 
    free(title); 
    return 5; 
     //close any remaining files 
} 


and this is my bmp2.h file 

    #include <stdint.h> 

/** 
* Common Data Types 
* 
* The data types in this section are essentially aliases for C/C++ 
* primitive data types. 
* 
* Adapted from http://msdn.microsoft.com/en-us/library/cc230309.aspx. 
* See http://en.wikipedia.org/wiki/Stdint.h for more on stdint.h. 
*/ 
typedef uint8_t BYTE; 
typedef uint32_t DWORD; 
typedef int32_t LONG; 
typedef uint16_t WORD; 

/** 
* BITMAPFILEHEADER 
* 
* The BITMAPFILEHEADER structure contains information about the type, size, 
* and layout of a file that contains a DIB [device-independent bitmap]. 
* 
* Adapted from http://msdn.microsoft.com/en-us/library/dd183374(VS.85).aspx. 
*/ 
typedef struct 
{ 
    WORD bfType; 
    DWORD bfSize; 
    WORD bfReserved1; 
    WORD bfReserved2; 
    DWORD bfOffBits; 
} __attribute__((__packed__)) 
BITMAPFILEHEADER; 

/** 
* BITMAPINFOHEADER 
* 
* The BITMAPINFOHEADER structure contains information about the 
* dimensions and color format of a DIB [device-independent bitmap]. 
* 
* Adapted from http://msdn.microsoft.com/en-us/library/dd183376(VS.85).aspx. 
*/ 
typedef struct 
{ 
    DWORD biSize; 
    LONG biWidth; 
    LONG biHeight; 
    WORD biPlanes; 
    WORD biBitCount; 
    DWORD biCompression; 
    DWORD biSizeImage; 
    LONG biXPelsPerMeter; 
    LONG biYPelsPerMeter; 
    DWORD biClrUsed; 
    DWORD biClrImportant; 
} __attribute__((__packed__)) 
BITMAPINFOHEADER; 

/** 
* RGBTRIPLE 
* 
* This structure describes a color consisting of relative intensities of 
* red, green, and blue. 
* 
* Adapted from http://msdn.microsoft.com/en-us/library/aa922590.aspx. 
*/ 
typedef struct 
{ 
    BYTE rgbtBlue; 
    BYTE rgbtGreen; 
    BYTE rgbtRed; 
} __attribute__((__packed__)) 
RGBTRIPLE; 


typedef struct 
{ 
    BYTE first; 
    BYTE second; 
    BYTE third; 
    BYTE fourth; 
} __attribute__((__packed__)) 
INTROJPG; 

typedef struct 
{ 
    BYTE image; 
} 
BYTEIMAGE; 
+1

У вас есть любимый отладчик? Выберите один сейчас, если вы этого не сделаете. –

+0

ну, я просто использую gdb, потому что тот, который включен в c9 ide, кажется, не работает. Это достаточно хорошо? –

+0

Вы задали тот же вопрос ca. 1 час назад. Если это было закрыто, вы должны следовать советам и редактировать его. Затем попросите снова открыть. ** Не возвращайте вопрос! ** – Olaf

ответ

0

Первые вещи первых, я постараюсь улучшить несколько вещей в вашем коде. Я также сделал это pset, и приятно помогать другим.

INTROJPG *buffer = (INTROJPG*)malloc(sizeof(INTROJPG)*x); 

В этой части, вы знаете, что размер обоих INTROJPG и х являются постоянными, поэтому нет необходимости постоянно выделять и свободной памяти на каждой итерации, что занимает гораздо больше времени, чем просто создание нормального массива , Кроме того, почему буфер является указателем на INTROJPG? Если это нужно только для проверки заголовка на каждой итерации, я не думаю, что это того стоит, вы можете просто получить доступ к первым 4 байтам обычного массива BYTE.

Я бы создал статический массив из 512 BYTE (структура в библиотеке), потому что это размер, который вы постоянно выделяете и освобождаете, а также вы используете BYTE, а не INTROJPG.

Во-вторых, на этом участке и другой аналогичный один:

for (int i = 0; i < 128; i++) 
{ 
    fread(&buffer[i], sizeof(INTROJPG), 1, card); 
} 

Там нет абсолютно никакой необходимости в этом цикле или, опять же, даже используя INTROJPG. Вы всегда чтение и запись 512 байт, вы можете использовать:

fread(buffer, 4, 128, card); 
// or even better 
fread(buffer, 512, 1, card); 

Теперь о вашей проблеме, я проверил свой код (без каких-либо модификаций) несколько раз и не нашел ничего плохого с image1.jpg и Image2.jpg , Да, я изменил режим «w» на «a» и наоборот.

Однако ваш код неисправен в отношении последнего изображения, последнее изображение - image49.jpg, когда должно быть изображение50.jpg, и ваш image49.jpg даже не открывается, и это потому, что цикл закончен до сохранения остальной части изображения49.jpg, т. е. вы сохраняете только первые 512 байт изображения49.jpg.

Чтобы исправить это, я изменил условие цикла do-while, чтобы продолжить работу до конца файла карты, IIRC проблема гарантирует, что последний блок является частью последнего изображения или что-то в этом роде, если не, это зависит от вас, чтобы исправить эту небольшую проблему!

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

#include "bmp2.h" 

int main(void) 
{ 
    /*OPEN CARD FILE*/ 
    char* infile = "card.raw";; 

    FILE* card = fopen(infile, "r"); 
    if (card == NULL) 
    { 
     printf("Could not open %s.\n", "card.raw"); 
     return 2; 
    } 

    int f = 0, c = 0, imageno = 1; 
    // c signals that a jpg is being written 
    // l size control, 0 means 0 jpgs 
    FILE* images; 
    char title[25]; 
    BYTE buffer[512]; 

    /*repeat until end of card*/ 
    do 
    { 

     fread(buffer, 512, 1, card); 

     if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff) 
     { 
      sprintf(title, "image%d.jpg", imageno); //change jpg title 

      if (f == 1) //close previous jpg 
      { 
       fclose(images); 
       imageno++; 
      } 

      images = fopen(title, "w"); 
      f = 1; //very first jpg has been opened 
      c = 1; //jpg open 
     } 

     //jpg already open? 
     if (c == 1) fwrite(buffer, 512, 1, images); 
    }  
    while (!feof(card)); 
    return 5; 
     //close any remaining files 
} 

Последнее, почему вы возвращаетесь 5 в конце программы? Просто любопытно.

+0

Эй, спасибо большое за помощь! Теперь мой код выглядит лучше. Btw, malloc используется только тогда, когда требуется много памяти? Скажем, если на одной итерации вам понадобилось 10 блоков, а в других 100, а затем обратно в 10. Было бы время использовать malloc? –

+0

О да, а возвращение 5 - это то, что я поставил, поэтому я знал, что произошло, когда я использовал эхо @? это ничего не значит, я думаю, что я должен использовать 1 или что-то в этом роде. BTW im все еще имеет проблемы с первым изображением, так как им должно быть всего 50 изображений, но я получаю только 49, и первое изображение каким-то образом потеряно для программы:/ –

+0

Кроме того, я просто заметил, что на card.raw что я опубликовал, все изображения извлечены (всего 50), но на моей карточке. Из фрейма в этом году извлекается только 49. weird –