https://exif-heic-js.github.io/exif-heic-js/example/
But I fail at the conversion to Purebasic. Probably because I'm doing something wrong with the unsigned data types.
This is the javascript code to find the exif items:
Code: Select all
function findEXIFinHEIC(data)
{
    var dataView = new DataView(data);
    var ftypeSize = dataView.getUint32(0); // size of ftype box
    var metadataSize = dataView.getUint32(ftypeSize); //size of metadata box
    //Scan through metadata until we find (a) Exif, (b) iloc
    var exifOffset = -1;
    var ilocOffset = -1;
    for (var i = ftypeSize; i < metadataSize + ftypeSize; i++)
    {
        if (getStringFromDB(dataView, i, 4) == "Exif")
        {
            exifOffset = i;
        } else if (getStringFromDB(dataView, i, 4) == "iloc")
        {
            ilocOffset = i;
        }
    }
    if (exifOffset == -1 || ilocOffset == -1)
    {
        return null;
    }
    var exifItemIndex = dataView.getUint16(exifOffset - 4);
    //Scan through ilocs to find exif item location
    for (var i = ilocOffset + 12; i < metadataSize + ftypeSize; i += 16)
    {
        var itemIndex = dataView.getUint16(i);
        if (itemIndex == exifItemIndex)
        {
            var exifLocation = dataView.getUint32(i + 8);
            var exifSize = dataView.getUint32(i + 12);
            //Check prefix at exif exifOffset
            var prefixSize = 4 + dataView.getUint32(exifLocation);
            var exifOffset = exifLocation + prefixSize;
            return readEXIFData(dataView, exifOffset);
        }
    }
    return null;
}
My first attempt. Seems that the value for 'exifLocation ' is determined incorrectly
Code: Select all
Procedure LoadHEICtoMem(file.s)
  Protected mem
  
  If ReadFile(0, file)
    mem = AllocateMemory(Lof(0))
    ReadData(0, mem, Lof(0))
  EndIf
  
  ProcedureReturn mem
EndProcedure
Procedure findEXIFinHEIC(mem)
  
  exifOffset = -1
  ilocOffset = -1
  
  Debug PeekS(mem + 4, 8, #PB_Ascii)
  
  If PeekS(mem + 4, 8, #PB_Ascii) = "ftypheic"
    
    For i = mem + 12 To mem + MemorySize(mem)
      If PeekS(i, 4, #PB_Ascii) = "Exif"
        exifOffset = i
        
      ElseIf PeekS(i, 4, #PB_Ascii) = "iloc"
        ilocOffset = i
        Break
      EndIf
    Next
    
  EndIf 
  
  Debug exifOffset
  Debug ilocOffset
  
  If exifOffset = -1 Or ilocOffset = -1
    ProcedureReturn 
  EndIf
  
  exifItemIndex.w = PeekW(exifOffset - 4) & $FFFF
  
  For i = ilocOffset + 12 To mem + MemorySize(mem) Step 16
   
    itemIndex.w = PeekW(i)  & $FFFF
    
    If itemIndex = exifItemIndex
      exifLocation = PeekL(i + 8)  & $FFFFFFFF
      exifSize     = PeekL(i + 12) & $FFFFFFFF
      
      Debug "Filesize      : " + StrU(MemorySize(mem))
      Debug "Memorypointer :" + StrU(mem)
      Debug "ExifLocation  : " + StrU(exifLocation)
      
      ;Check prefix at exif exifOffset
      prefixSize = 4 + PeekL(exifLocation)    ; <--- Illegal memory access
      exifOffset = exifLocation + prefixSize
      
      Debug exifOffset
      
       ;Return readEXIFData(dataView, exifOffset);
    EndIf
  Next
EndProcedure
Does anyone want to help?
