C программа читает из файла неправильно

У меня есть следующий код, написанный на c. Он открывает файл JPEG и получает некоторые данные из него на основе определенных позиций файла. Вывод правильный для "Изготовителя" и "Модели", но не для чего-либо еще. В присваивании это когда tagIdentifier равен 0x8827, что ему нужно перейти на место в файле, расположенное по значению tiff.value ofDataItem.

Из задания: "Если мы столкнемся с идентификатором 0x8769, в другом месте файла есть дополнительный блок Exif. Мы можем прекратить чтение на этом этапе, даже если мы не прочитали все теги count, потому что формат TIFF гласит, что все идентификаторы должны быть в отсортированном порядке. Мы будем искать конкретное oset в этом теге подблока Exif, снова +12 байт. Там, хорошо повторить вышеупомянутый процесс еще раз, чтобы получить более конкретную информацию об изображении. Сначала прочитайте в новом отсчете как короткий без знака. Далее цикл, читающий из файла больше 12-байтовых тегов TIFF."

Он выводит правильного производителя и модель, но больше ничего не работает. Это проблема чтения из неправильного места в файле или неправильного чтения в целых. Кроме того, он говорит, что 0x829A, 0x829D, 0x920A (дробь 2 32-разрядных целых чисел без знака). Там написано, что они "ведут себя так, как мы это делали со строкой, но вместо того, чтобы читать несколько однобайтовых символов, прочитайте 2 беззнаковых целых. Я тоже не знаю, как это сделать.

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

  struct EXIF{
    unsigned short startOfFile;
    unsigned short JPEGAPP1marker;
    unsigned short lengthOfAPP1block;
    unsigned char exitString[4];
    unsigned short nullTerminator;
    unsigned char endianness[2];
    unsigned short versionNumber;
    unsigned int offsettoTIFFblock;

 };

  struct TIFF{
    unsigned short tagIdentifier;
    unsigned short dataType;
    unsigned int numOfDataItems;
    unsigned int valueOfDataItem;

  };

   int main(int argc, char *argv[]){

    int i;
    FILE *fp;
    fp = fopen(argv[1], "rb+");

    if(fp == NULL){
            perror("ERROR!");
            exit(1);
    }

    struct EXIF exif;
      int x = fread(&exif, sizeof(struct EXIF), 1, fp);

    unsigned short count;
    int y = fread(&count, sizeof(short), 1, fp);

    struct TIFF tiff;
    int location = 22;
    char manufacturer[15];
    char cameraModel[50];
    unsigned int exifBlock;

    for(i = 0; i < count; i++){
            fread(&tiff, sizeof(struct TIFF), 1, fp);
            if(tiff.tagIdentifier == 0x010F){
                    fseek(fp, tiff.valueOfDataItem + 12, SEEK_SET);
                    fread(manufacturer, sizeof(char), tiff.numOfDataItems, f$
            }
            if(tiff.tagIdentifier == 0x0110){
                fseek(fp, tiff.valueOfDataItem + 12, SEEK_SET);
                 fread(cameraModel, sizeof(char), tiff.numOfDataItems, fp$

            }
            if(tiff.tagIdentifier == 0x8769){
                    fseek(fp, tiff.valueOfDataItem + 12, SEEK_SET);
                    location = tiff.valueOfDataItem + 12;
                    break;

            }
            location = location + 12;
            fseek(fp, location, SEEK_SET);
    }

    unsigned short newCount;
    int z = fread(&newCount, sizeof(short), 1, fp);
    int j;
    int width;
    int height;
    int ISOspeed;
    char dateTaken[2];

    for(j = 0; j < newCount; j++){
            fread(&tiff, sizeof(struct TIFF), 1, fp);
            if(tiff.tagIdentifier == 0xA002){
                    fseek(fp, tiff.valueOfDataItem + 12, SEEK_SET);
                    fread(&width, sizeof(int), tiff.numOfDataItems, fp);

            }
            if(tiff.tagIdentifier == 0xA003){
                    fseek(fp, tiff.valueOfDataItem + 12, SEEK_SET);
                    fread(&height, sizeof(int), tiff.numOfDataItems, fp);

            }
            if(tiff.tagIdentifier == 0x8827){
                    fseek(fp, tiff.valueOfDataItem + 12, SEEK_SET);
                    location = tiff.valueOfDataItem + 12;
                    break;

            }
            location = location + 12;
            fseek(fp, location, SEEK_SET);
    }
    unsigned short newCount;
    int z = fread(&newCount, sizeof(short), 1, fp);
    int j;
    int width;
    int height;
    int ISOspeed;
    char dateTaken[2];
    int exposureTime;
    int focalLength;
    int fstop;


    for(j = 0; j < newCount; j++){
            fread(&tiff, sizeof(struct TIFF), 1, fp);
            if(tiff.tagIdentifier == 0xA002){
                    fseek(fp, tiff.valueOfDataItem + 12, SEEK_SET);
                    fread(&width, sizeof(int), tiff.numOfDataItems, fp);

            }
            if(tiff.tagIdentifier == 0xA003){
                    fseek(fp, tiff.valueOfDataItem + 12, SEEK_SET);
                    fread(&height, sizeof(int), tiff.numOfDataItems, fp);

            }
            if(tiff.tagIdentifier == 0x8827){
                    fseek(fp, tiff.valueOfDataItem + 12, SEEK_SET);
                    fread(&ISOspeed, sizeof(int), tiff.numOfDataItems, fp);

    }if(tiff.tagIdentifier == 0x829A){
                    fseek(fp, tiff.valueOfDataItem + 12, SEEK_SET);
                    fread(&exposureTime, sizeof(int), tiff.numOfDataItems, fp);

            }if(tiff.tagIdentifier == 0x829D){
                    fseek(fp, tiff.valueOfDataItem + 12, SEEK_SET);
                    fread(&fstop, sizeof(int), tiff.numOfDataItems, fp);

            }
            if(tiff.tagIdentifier == 0x920A){
                    fseek(fp, tiff.valueOfDataItem + 12, SEEK_SET);
                    fread(&focalLength, sizeof(int), tiff.numOfDataItems, fp);

            }
            if(tiff.tagIdentifier == 0x9003){
                    fseek(fp, tiff.valueOfDataItem + 12, SEEK_SET);
                    fread(dateTaken, sizeof(char), tiff.numOfDataItems, fp);
            }
             location = location + 12;
            fseek(fp, location, SEEK_SET);
    }


    printf("Manufacturer: %s\n", manufacturer);
    printf("Model: %s\n", cameraModel);
    printf("Width: %d pixels\n", width);
    printf("Height: %d pixels\n", height);
    printf("Date taken: %s\n", dateTaken);



    fclose(fp);
    return 0;
}

1 ответ

Есть несколько проблем с вашим кодом. Как упоминалось ранее, вы принимаете положение маркера EXIF.

Кроме того, вы принимаете макет структуры. Компилятор может выравнивать элементы, отбрасывая все.

Вы также не учитываете порядок байтов. Если вы работаете на процессоре с прямым порядком байтов, ваш код не будет работать.

Вам нужно прочитать массивы байтов. Для целых чисел вам нужно привести указатели к определенным элементам массива, и вам необходимо исправить порядок байтов, если это необходимо.

Другие вопросы по тегам