evanoberholster / imagemeta

Image Metadata (Exif and XMP) extraction for JPEG, HEIC, AVIF, TIFF and Camera Raw in golang. Focus is on providing features and improved performance.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Incorrect Tiff Header ImageType

dschwarz9319 opened this issue · comments

Hi Evan,

I really like this GO package and I appreciate your constant work to update and progress the codebase in it. I'm using it in tandem with Canon's own API (CCAPI) on their cameras to automate photo upload, naming, and tagging. I ran into an issue(possibly a bug), whilst trying to retrieve the * rating imbedded in the exif/tiff data. (NOT the ISOSPEEDRATING)

Without bogging you down with too much code, I have a function that calls both imageType.Scan() as well as tiff.ScanTiffHeader() listed below:

// GetImageType returns the type of file passed in through the 'path' parameter
func GetImageType(path string) (string, utils.HTTPError) {
	file, err := os.Open(path)
	if err != nil {
		return "", utils.HTTPError{
			Error:      utils.ErrorTrace(err, "Error Opening Specified File Path"+path),
			StatusCode: 500,
		}
	}
	defer file.Close()

	fileType, err := imagetype.Scan(file)
	if err != nil {
		return "", utils.HTTPError{
			Error:      utils.ErrorTrace(err, "Error Determining ImageType of"+path),
			StatusCode: 500,
		}
	}

	unformattedImageType := fileType.String()
	returnImageType := (strings.Trim(unformattedImageType, "image/"))
	if returnImageType == "jp" || returnImageType == "jpg" {
		returnImageType = "jpeg" // Renamed for Consistency
	}

	fmt.Println("\nImage type from imageType.Scan():")
	fmt.Println(fileType.String())

	br := bufio.NewReader(file)

	// Same result if imageType is harded-coded ↓↓↓
	// header, err := tiff.ScanTiffHeader(br, imagetype.ImageCR3)
	header, err := tiff.ScanTiffHeader(br, fileType)
	if err != nil {
		return "", utils.HTTPError{
			Error:      utils.ErrorTrace(err, "Error Creating Tiff Header"),
			StatusCode: 500,
		}
	}

	fmt.Println("\n\nTiff Header Values from ScanTiffHeader():")
	fmt.Println(header.String())

	fmt.Println("\n\nCheck if Header is valid:")
	fmt.Println(header.IsValid())

	return returnImageType, utils.HTTPError{Error: nil, StatusCode: 200}
}

It successfully retrieves the fileType, however the diff header always returns the incorrect fileType, even if it's hard-coded in. Here's a terminal output of the above code. (It's from a RESTful API)

[GIN-debug] Listening and serving HTTP on :8080


Image type from imageType.Scan():
image/x-canon-cr3


Tiff Header Values from ScanTiffHeader():
ByteOrder: LittleEndian, Ifd: Ifd, Offset: 0x0008 TiffOffset: 0x0128 Length: 0 Imagetype: application/octet-stream


Check if Header is valid:
true


2022/08/19 15:29:06 No Lens Make found for file: C:/Users/Daniel/Desktop/upload/IMGL2080.cr3

2022/08/19 15:29:06 GetMetadata() Finished Successfully. Total Time Elapsed:113.5163ms

[GIN] 2022/08/19 - 15:29:06 |←[97;42m 200 ←[0m|    115.5137ms |          ::1 |←[97;44m GET     ←[0m "/photo/metadata"

The image I referenced using the path variable in the code is in .CR3 raw format, and can be found here

Additionally, I really just need that * rating from the exifdata. I'm able to view it using Phil Harvey's exiftools utility, but I was having issues figuring out a way to retrieve it using your go package.

Do you have a quick code snippet that you wouldn't mind sharing that can do this? The only mention of rating (without ISO attached) in your codebase is located in imagemetadata/exif/ifds/rootifd.go:

I appreciate any assistance you're able to provide, and thanks again for this repo! :D

@dschwarz9319 Thanks for opening the issue.

Regarding your first concern:

  • I need to simplify the exif library as to produce less confusion.
  • Please use imagemeta.Parse() function

Regarding the Exif/Rating:

  • This is sometimes set in JPEG images. in CR3 images it remains unset. The rating field you are looking for comes from XMP embedded within the CR3 exif information:

Below is the exif XMP field from your image.

<?xpacket begin='' id='W5M0MpCehiHzreSzNTczkc9d'?>
   <x:xmpmeta xmlns:x="adobe:ns:meta/">
     <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
        <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/">
           <xmp:Rating>1</xmp:Rating>
        </rdf:Description>
     </rdf:RDF>
   </x:xmpmeta> 
<?xpacket end='w'?>

Closing this issue. If there are further concerns please reopen.