1#------------------------------------------------------------------------------
2# File:         ZISRAW.pm
3#
4# Description:  Read ZISRAW (CZI) meta information
5#
6# Revisions:    2020-08-07 - P. Harvey Created
7#
8# References:   1) https://www.zeiss.com/microscopy/us/products/microscope-software/zen/czi.html
9#------------------------------------------------------------------------------
10
11package Image::ExifTool::ZISRAW;
12
13use strict;
14use vars qw($VERSION);
15use Image::ExifTool qw(:DataAccess :Utils);
16
17$VERSION = '1.00';
18
19%Image::ExifTool::ZISRAW::Main = (
20    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
21    GROUPS => { 0 => 'File', 1 => 'File', 2 => 'Image' },
22    NOTES => q{
23        As well as the header information listed below, ExifTool also extracts the
24        top-level XML-based metadata from Zeiss Integrated Software RAW (ZISRAW) CZI
25        files.
26    },
27    0x20 => {
28        Name => 'ZISRAWVersion',
29        Format => 'int32u[2]',
30        PrintConv => '$val =~ tr/ /./; $val',
31    },
32    0x30 => {
33        Name => 'PrimaryFileGUID',
34        Format => 'undef[16]',
35        ValueConv => 'unpack("H*",$val)',
36    },
37    0x40 => {
38        Name => 'FileGUID',
39        Format => 'undef[16]',
40        ValueConv => 'unpack("H*",$val)',
41    },
42);
43
44#------------------------------------------------------------------------------
45# Extract metadata from a ZISRAW (CZI) image
46# Inputs: 0) ExifTool object reference, 1) dirInfo reference
47# Returns: 1 on success, 0 if this wasn't a valid CZI file
48sub ProcessCZI($$)
49{
50    my ($et, $dirInfo) = @_;
51    my $raf = $$dirInfo{RAF};
52    my ($buff, $tagTablePtr);
53
54    # verify this is a valid CZI file
55    return 0 unless $raf->Read($buff, 100) == 100;
56    return 0 unless $buff =~ /^ZISRAWFILE\0{6}/;
57    $et->SetFileType();
58    SetByteOrder('II');
59    my %dirInfo = (
60        DataPt => \$buff,
61        DirStart => 0,
62        DirLen => length($buff),
63    );
64    $tagTablePtr = GetTagTable('Image::ExifTool::ZISRAW::Main');
65    $et->ProcessDirectory(\%dirInfo, $tagTablePtr);
66
67    # read the metadata section
68    my $pos = Get64u(\$buff, 92) or return 1;
69    $raf->Seek($pos, 0) or $et->Warn('Error seeking to metadata'), return 0;
70    $raf->Read($buff, 288) == 288 or $et->Warn('Error reading metadata header'), return 0;
71    $buff =~ /^ZISRAWMETADATA\0\0/ or $et->Warn('Invalid metadata header'), return 0;
72    my $len = Get32u(\$buff, 32);
73    $len < 200000000 or $et->Warn('Metadata section too large. Ignoring'), return 0;
74    $raf->Read($buff, $len) or $et->Warn('Error reading XML metadata'), return 0;
75    $et->FoundTag('XML', $buff);    # extract as a block
76    $tagTablePtr = GetTagTable('Image::ExifTool::XMP::XML');
77    $dirInfo{DirLen} = length $buff;
78    # shorten tag names somewhat by removing 'ImageDocumentMetadata' prefix from all
79    $$et{XmpIgnoreProps} = [ 'ImageDocument', 'Metadata' ];
80    $et->ProcessDirectory(\%dirInfo, $tagTablePtr);
81
82    return 1;
83}
84
851;  # end
86
87__END__
88
89=head1 NAME
90
91Image::ExifTool::ZISRAW - Read ZISRAW (CZI) meta information
92
93=head1 SYNOPSIS
94
95This module is used by Image::ExifTool
96
97=head1 DESCRIPTION
98
99This module contains definitions required by Image::ExifTool to read
100metadata from Zeiss Integrated Software RAW (ZISRAW) CZI files.
101
102=head1 AUTHOR
103
104Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
105
106This library is free software; you can redistribute it and/or modify it
107under the same terms as Perl itself.
108
109=head1 REFERENCES
110
111=over 4
112
113=item L<https://www.zeiss.com/microscopy/us/products/microscope-software/zen/czi.html>
114
115=back
116
117=head1 SEE ALSO
118
119L<Image::ExifTool::TagNames/ZISRAW Tags>,
120L<Image::ExifTool(3pm)|Image::ExifTool>
121
122=cut
123
124