void create_EXIF(void)
{
    char Buffer[256];

    unsigned short NumEntries;
    int DataWriteIndex;
    int DateIndex;
    int DirIndex;
    int DirContinuation;
    
    MotorolaOrder = 0;

    memcpy(Buffer+2, "Exif\0\0II",8);
    Put16u(Buffer+10, 0x2a);

    DataWriteIndex = 16;
    Put32u(Buffer+12, DataWriteIndex-8); // first IFD offset.  Means start 16 bytes in.

    {
        DirIndex = DataWriteIndex;
        NumEntries = 2;
        DataWriteIndex += 2 + NumEntries*12 + 4;

        Put16u(Buffer+DirIndex, NumEntries); // Number of entries
        DirIndex += 2;
  
        // Enitries go here...
        {
            // Date/time entry
            Put16u(Buffer+DirIndex, TAG_DATETIME);         // Tag
            Put16u(Buffer+DirIndex + 2, FMT_STRING);       // Format
            Put32u(Buffer+DirIndex + 4, 20);               // Components
            Put32u(Buffer+DirIndex + 8, DataWriteIndex-8); // Pointer or value.
            DirIndex += 12;

            DateIndex = DataWriteIndex;
            if (ImageInfo.numDateTimeTags){
                // If we had a pre-existing exif header, use time from that.
                memcpy(Buffer+DataWriteIndex, ImageInfo.DateTime, 19);
                Buffer[DataWriteIndex+19] = '\0';
            }else{
                // Oterwise, use the file's timestamp.
                FileTimeAsString(Buffer+DataWriteIndex);
            }
            DataWriteIndex += 20;
        
            // Link to exif dir entry
            Put16u(Buffer+DirIndex, TAG_EXIF_OFFSET);      // Tag
            Put16u(Buffer+DirIndex + 2, FMT_ULONG);        // Format
            Put32u(Buffer+DirIndex + 4, 1);                // Components
            Put32u(Buffer+DirIndex + 8, DataWriteIndex-8); // Pointer or value.
            DirIndex += 12;
        }

        // End of directory - contains optional link to continued directory.
        DirContinuation = DirIndex;
    }

    {
        DirIndex = DataWriteIndex;
        NumEntries = 1;
        DataWriteIndex += 2 + NumEntries*12 + 4;

        Put16u(Buffer+DirIndex, NumEntries); // Number of entries
        DirIndex += 2;

        // Original date/time entry
        Put16u(Buffer+DirIndex, TAG_DATETIME_ORIGINAL);         // Tag
        Put16u(Buffer+DirIndex + 2, FMT_STRING);       // Format
        Put32u(Buffer+DirIndex + 4, 20);               // Components
        Put32u(Buffer+DirIndex + 8, DataWriteIndex-8); // Pointer or value.
        DirIndex += 12;

        memcpy(Buffer+DataWriteIndex, Buffer+DateIndex, 20);
        DataWriteIndex += 20;
        
        // End of directory - contains optional link to continued directory.
        Put32u(Buffer+DirIndex, 0);
    }

    {
        //Continuation which links to this directory;
        Put32u(Buffer+DirContinuation, DataWriteIndex-8);
        DirIndex = DataWriteIndex;
        NumEntries = 2;
        DataWriteIndex += 2 + NumEntries*12 + 4;

        Put16u(Buffer+DirIndex, NumEntries); // Number of entries
        DirIndex += 2;
        {
            // Link to exif dir entry
            Put16u(Buffer+DirIndex, TAG_THUMBNAIL_OFFSET);         // Tag
            Put16u(Buffer+DirIndex + 2, FMT_ULONG);       // Format
            Put32u(Buffer+DirIndex + 4, 1);               // Components
            Put32u(Buffer+DirIndex + 8, DataWriteIndex-8); // Pointer or value.
            DirIndex += 12;
        }

        {
            // Link to exif dir entry
            Put16u(Buffer+DirIndex, TAG_THUMBNAIL_LENGTH);         // Tag
            Put16u(Buffer+DirIndex + 2, FMT_ULONG);       // Format
            Put32u(Buffer+DirIndex + 4, 1);               // Components
            Put32u(Buffer+DirIndex + 8, 0); // Pointer or value.
            DirIndex += 12;
        }

        // End of directory - contains optional link to continued directory.
        Put32u(Buffer+DirIndex, 0);
    }

    
    Buffer[0] = (unsigned char)(DataWriteIndex >> 8);
    Buffer[1] = (unsigned char)DataWriteIndex;

    // Remove old exif section, if there was one.
    RemoveSectionType(M_EXIF);

    {
        // Sections need malloced buffers, so do that now, especially because
        // we now know how big it needs to be allocated.
        unsigned char * NewBuf = malloc(DataWriteIndex);
        if (NewBuf == NULL){
            ErrFatal("Could not allocate memory");
        }
        memcpy(NewBuf, Buffer, DataWriteIndex);

        CreateSection(M_EXIF, NewBuf, DataWriteIndex);

        // Re-parse new exif section, now that its in place
        // otherwise, we risk touching data that has already been freed.
        process_EXIF(NewBuf, DataWriteIndex);
    }
}
void create_EXIF(void)
{
    char Buffer[256];

    unsigned short NumEntries;
    int DataWriteIndex;
    int DateIndex;
    int DirIndex;
    int DirContinuation;
    
    MotorolaOrder = 0;

    memcpy(Buffer+2, "Exif\0\0II",8);
    Put16u(Buffer+10, 0x2a);

    DataWriteIndex = 16;
    Put32u(Buffer+12, DataWriteIndex-8);  

    {
        DirIndex = DataWriteIndex;
        NumEntries = 2;
        DataWriteIndex += 2 + NumEntries*12 + 4;

        Put16u(Buffer+DirIndex, NumEntries);  
        DirIndex += 2;
  
         
        {
             
            Put16u(Buffer+DirIndex, TAG_DATETIME);          
            Put16u(Buffer+DirIndex + 2, FMT_STRING);        
            Put32u(Buffer+DirIndex + 4, 20);                
            Put32u(Buffer+DirIndex + 8, DataWriteIndex-8);  
            DirIndex += 12;

            DateIndex = DataWriteIndex;
            if (ImageInfo.numDateTimeTags){
                 
                memcpy(Buffer+DataWriteIndex, ImageInfo.DateTime, 19);
                Buffer[DataWriteIndex+19] = '\0';
            }else{
                 
                FileTimeAsString(Buffer+DataWriteIndex);
            }
            DataWriteIndex += 20;
        
             
            Put16u(Buffer+DirIndex, TAG_EXIF_OFFSET);       
            Put16u(Buffer+DirIndex + 2, FMT_ULONG);         
            Put32u(Buffer+DirIndex + 4, 1);                 
            Put32u(Buffer+DirIndex + 8, DataWriteIndex-8);  
            DirIndex += 12;
        }

         
        DirContinuation = DirIndex;
    }

    {
        DirIndex = DataWriteIndex;
        NumEntries = 1;
        DataWriteIndex += 2 + NumEntries*12 + 4;

        Put16u(Buffer+DirIndex, NumEntries);  
        DirIndex += 2;

         
        Put16u(Buffer+DirIndex, TAG_DATETIME_ORIGINAL);          
        Put16u(Buffer+DirIndex + 2, FMT_STRING);        
        Put32u(Buffer+DirIndex + 4, 20);                
        Put32u(Buffer+DirIndex + 8, DataWriteIndex-8);  
        DirIndex += 12;

        memcpy(Buffer+DataWriteIndex, Buffer+DateIndex, 20);
        DataWriteIndex += 20;
        
         
        Put32u(Buffer+DirIndex, 0);
    }

    {
         
        Put32u(Buffer+DirContinuation, DataWriteIndex-8);
        DirIndex = DataWriteIndex;
        NumEntries = 2;
        DataWriteIndex += 2 + NumEntries*12 + 4;

        Put16u(Buffer+DirIndex, NumEntries);  
        DirIndex += 2;
        {
             
            Put16u(Buffer+DirIndex, TAG_THUMBNAIL_OFFSET);          
            Put16u(Buffer+DirIndex + 2, FMT_ULONG);        
            Put32u(Buffer+DirIndex + 4, 1);                
            Put32u(Buffer+DirIndex + 8, DataWriteIndex-8);  
            DirIndex += 12;
        }

        {
             
            Put16u(Buffer+DirIndex, TAG_THUMBNAIL_LENGTH);          
            Put16u(Buffer+DirIndex + 2, FMT_ULONG);        
            Put32u(Buffer+DirIndex + 4, 1);                
            Put32u(Buffer+DirIndex + 8, 0);  
            DirIndex += 12;
        }

         
        Put32u(Buffer+DirIndex, 0);
    }

    
    Buffer[0] = (unsigned char)(DataWriteIndex >> 8);
    Buffer[1] = (unsigned char)DataWriteIndex;

     
    RemoveSectionType(M_EXIF);

    {
         
         
        unsigned char * NewBuf = malloc(DataWriteIndex);
        if (NewBuf == NULL){
            ErrFatal("Could not allocate memory");
        }
        memcpy(NewBuf, Buffer, DataWriteIndex);

        CreateSection(M_EXIF, NewBuf, DataWriteIndex);

         
         
        process_EXIF(NewBuf, DataWriteIndex);
    }
}