#------------------------------------------------------------------------------ # File: XISF.pm # # Description: Read Extensible Image Serialization Format metadata # # Revisions: 2023-10-10 - P. Harvey Created # # References: 1) https://pixinsight.com/doc/docs/XISF-1.0-spec/XISF-1.0-spec.html #------------------------------------------------------------------------------ package Image::ExifTool::XISF; use strict; use vars qw($VERSION); use Image::ExifTool qw(:DataAccess :Utils); use Image::ExifTool::XMP; $VERSION = '1.00'; # XISF tags (ref 1) %Image::ExifTool::XISF::Main = ( GROUPS => { 0 => 'XML', 1 => 'XML', 2 => 'Image' }, VARS => { LONG_TAGS => 1 }, NOTES => q{ This table lists some standard Extensible Image Serialization Format (XISF) tags, but ExifTool will extract any other tags found. See L for the specification. }, ImageGeometry => { }, ImageSampleFormat => { }, ImageBounds => { }, ImageImageType => { Name => 'ImageType' }, ImageColorSpace => { Name => 'ColorSpace' }, ImageLocation => { }, ImageResolutionHorizontal => 'XResolution', ImageResolutionVertical => 'YResolution', ImageResolutionUnit => 'ResolutionUnit', ImageICCProfile => { Name => 'ICC_Profile', ValueConv => 'Image::ExifTool::XMP::DecodeBase64($val)', Binary => 1, }, ImageICCProfileLocation => { Name => 'ICCProfileLocation' }, ImagePixelStorage => { }, ImageOffset => { Name => 'ImagePixelOffset' }, ImageOrientation => { Name => 'Orientation' }, ImageId => { Name => 'ImageID' }, ImageUuid => { Name => 'UUID' }, ImageData => { Binary => 1 }, 'CreationTime' => { Name => 'CreateDate', Shift => 'Time', Groups => { 2 => 'Time' }, ValueConv => 'Image::ExifTool::XMP::ConvertXMPDate($val)', PrintConv => '$self->ConvertDateTime($val)', }, CreatorApplication => { }, Abstract => { }, AccessRights => { }, Authors => { Groups => { 2 => 'Author' } }, BibliographicReferences => { }, BriefDescription => { }, CompressionLevel => { }, CompressionCodecs => { }, Contributors => { Groups => { 2 => 'Author' } }, Copyright => { Groups => { 2 => 'Author' } }, CreatorModule => { }, CreatorOS => { }, Description => { }, Keywords => { }, Languages => { }, License => { }, OriginalCreationTime => { Name => 'DateTimeOriginal', Description => 'Date/Time Original', Shift => 'Time', Groups => { 2 => 'Time' }, ValueConv => 'Image::ExifTool::XMP::ConvertXMPDate($val)', PrintConv => '$self->ConvertDateTime($val)', }, RelatedResources => { }, Title => { }, ); #------------------------------------------------------------------------------ # Handle properties in XISF metadata structures # Inputs: 0) attribute list ref, 1) attr hash ref, # 2) property name ref, 3) property value ref # Returns: true if value was changed sub HandleXISFAttrs($$$$) { my ($attrList, $attrs, $prop, $valPt) = @_; return 0 unless defined $$attrs{id}; my ($changed, $a); # use "id" as the tag name, "value" as the value, and ignore "type" $$prop = $$attrs{id}; $$prop =~ s/^XISF://; # remove XISF namespace if (defined $$attrs{value}) { $$valPt = $$attrs{value}; $changed = 1; } my @attrs = @$attrList; @$attrList = ( ); foreach $a (@attrs) { if ($a eq 'id' or $a eq 'value' or $a eq 'type') { delete $$attrs{$a}; } else { push @$attrList, $a; } } return $changed; } #------------------------------------------------------------------------------ # Read information in a XISF document # Inputs: 0) ExifTool ref, 1) dirInfo ref # Returns: 1 on success, 0 if this wasn't a valid XISF file sub ProcessXISF($$) { my ($et, $dirInfo) = @_; my $raf = $$dirInfo{RAF}; my $buff; return 0 unless $raf->Read($buff, 16) == 16 and $buff =~ /^XISF0100/; $et->SetFileType(); SetByteOrder('II'); my $tagTablePtr = GetTagTable('Image::ExifTool::XISF::Main'); my $hdrLen = Get32u(\$buff, 8); $raf->Read($buff, $hdrLen) == $hdrLen or $et->Warn('Error reading XISF header'), return 1; $et->FoundTag(XML => $buff); my %dirInfo = ( DataPt => \$buff, IgnoreProp => { xisf => 1, Metadata => 1, Property => 1 }, XMPParseOpts => { AttrProc => \&HandleXISFAttrs }, ); Image::ExifTool::XMP::ProcessXMP($et, \%dirInfo, $tagTablePtr); my $geo = $$et{VALUE}{ImageGeometry}; if ($geo) { my ($w, $h, $n) = split /:/, $geo; $et->FoundTag(ImageWidth => $w); $et->FoundTag(ImageHeight => $h); $et->FoundTag(NumPlanes => $n); } return 1; } 1; # end __END__ =head1 NAME Image::ExifTool::XISF - Read Extensible Image Serialization Format metadata =head1 SYNOPSIS This module is used by Image::ExifTool =head1 DESCRIPTION This module contains definitions required by Image::ExifTool to read meta information from XISF (Extensible Image Serialization Format) images. =head1 AUTHOR Copyright 2003-2024, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =head1 REFERENCES =over 4 =item L =back =head1 SEE ALSO L, L =cut