简体   繁体   中英

C program reading from a file incorrectly

I have the following code written in c. It opens a JPEG file and gets some data from it based on certain positions of the file. The output is correct for "Manufacturer" and "Model" but not for anything else. In the assignment it when tagIdentifier is equal to 0x8827 that it needs to go to a spot in the file located by the value of tiff.valueofDataItem.

From the assignment: "If we encounter the 0x8769 identifer, there is an additional Exif block elsewhere in the le. We can stop reading at this point even if we haven't read all count tags because the TIFF format states that all identiers must be in sorted order. We will seek to the oset specific in this Exif sub block tag, again +12 bytes. There, well repeat the above process one more time to get more specific information about the picture. First, read in a new count as an unsigned short. Next, loop, reading more 12-byte TIFF tags from the file."

It outputs the correct Manufacturer and Model but nothing else works. Is it a problem of reading from the wrong spot in the file or reading in ints wrong. Also, it says that 0x829A, 0x829D, 0x920A are (fraction of 2 32-bit unsigned integers). It says they "behave like we did the with string, but rather than reading several single-byte characters, read 2 unsigned ints. I don't know how to this either.

  #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;
}

There are several problems with your code. As mentioned previously, you assume the position of the EXIF marker.

Also, you assume the layout of the structure. The compiler could align members throwing everything off.

You also do not take into account byte ordering. If you are running on a little-endian processor, your code will not work.

You need to read arrays of bytes. For integers, you need to cast pointers to specific array elements and you need to correct for the byte ordering, if necessary.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM