From d6125e8941314414d5082e1936e632fcf83a552b Mon Sep 17 00:00:00 2001
From: Yoann Guilhem <yoann.guilhem@esrf.fr>
Date: Thu, 25 Apr 2013 11:13:24 +0200
Subject: [PATCH] Update TIF IO functions.

Signed-off-by: Yoann Guilhem <yoann.guilhem@esrf.fr>
---
 zUtil_TIFF/gtTIFInfoReader.m        | 44 ++++++++++++++++++++
 zUtil_TIFF/gtTIFVolReader.m         | 54 ++++++++++++++++---------
 zUtil_TIFF/gtTIFVolReaderWithInfo.m | 41 +++++++++++++++++++
 zUtil_TIFF/gtTIFVolWriter.m         | 63 ++++++++++++++++++-----------
 4 files changed, 159 insertions(+), 43 deletions(-)
 create mode 100644 zUtil_TIFF/gtTIFInfoReader.m
 create mode 100644 zUtil_TIFF/gtTIFVolReaderWithInfo.m

diff --git a/zUtil_TIFF/gtTIFInfoReader.m b/zUtil_TIFF/gtTIFInfoReader.m
new file mode 100644
index 00000000..599096bb
--- /dev/null
+++ b/zUtil_TIFF/gtTIFInfoReader.m
@@ -0,0 +1,44 @@
+function info = gtTIFInfoReader(filename, info)
+% GTTIFINFOREADER  Read TIFF info file (BBox, voxelsize and origin).
+%
+%     info = gtTIFInfoReader(filename, info)
+%     -------------------------------------------------------------------------
+%
+%     INPUT:
+%       filename     = <string>  Path to info file
+%
+%     OPTIONAL INPUT
+%       info         = <struct>  TIFF info strsture to complete
+%
+%     OUTPUT:
+%       info       = <struct>  Information about volume
+%
+%     Note:
+%       info file should be formatted as the following:
+%
+%       [bboxMinX, bboxMinY, bboxMinZ] [bboxMaxX, bboxMaxY, bboxMaxZ]
+%       voxelsize
+%
+%     Version 001 24-04-2013 by YGuilhem, yoann.guilhem@esrf.fr
+
+% Check existence of file
+if ~exist(filename, 'file')
+    gtError('gtTIFInfoReader:wrong_file_name', ...
+        ['File ''' filename ''' does not exist!']);
+end
+
+% Read info file
+fid = fopen(filename, 'r');
+bbox = fscanf(fid, '[%d, %d, %d] [%d, %d, %d]', 6).';
+vSize = fscanf(fid, '%f', 1);
+fclose(fid);
+
+% Store bbox, voxel size and origin
+info.boundingBoxMin = bbox(1:3) + 1;
+info.boundingBoxMax = bbox(4:6);
+info.voxelSize = vSize;
+info.origin = bbox(1:3) .* info.voxelSize;
+info.infoFile = filename;
+
+end % end of function
+
diff --git a/zUtil_TIFF/gtTIFVolReader.m b/zUtil_TIFF/gtTIFVolReader.m
index 50d807c1..96e99512 100644
--- a/zUtil_TIFF/gtTIFVolReader.m
+++ b/zUtil_TIFF/gtTIFVolReader.m
@@ -10,23 +10,22 @@ function [vol, info] = gtTIFVolReader(filename, varargin)
 %                                if extension is missing, '.tif' is append
 %
 %     OPTIONAL INPUT (varargin as a list of pairs, see parse_pv_pairs.m):
-%       'xrange'     = <range>   Index range of output in X direction
-%       'yrange'     = <range>               "            Y     "
-%       'zrange'     = <range>               "            Z     "
-%       'mode'       = <string>  Input type which is either 'single' or 'stack'
-%                                default is a single TIFF file
-%       'digits'     = <int>     Number of digits in stack filenames
-%       'startindex' = <int>     Starting index for stack filenames
-%       'endindex'   = <int>     Ending             "
-%       'filext'     = <string>  Input TIFF file extension ('tif' or 'tiff')
-%                                default is 'tif'
-%       'newMethod'  = <bool>    Use new reading method (faster)
+%       'xrange'     = <range>   Index range of output in X direction {'all'}
+%       'yrange'     = <range>               "            Y     "     {'all'}
+%       'zrange'     = <range>               "            Z     "     {'all'}
+%       'bbox'       = <int>     Index range as bbox [Xi Yi Zi Xf Yf Zf]
+%       'mode'       = <string>  Input type which is {'single'} or 'stack'
+%       'digits'     = <int>     Number of digits in stack filenames {4}
+%       'startindex' = <int>     Starting index for stack filenames {1}
+%       'endindex'   = <int>     Ending             "               {1}
+%       'filext'     = <string>  Input TIFF file extension {'tif'}
+%       'newMethod'  = <bool>    Use new reading method (faster) {'true'}
 %
 %     OUTPUT:
-%       vol        = <3Dimage> Output 3D volume
-%       info       = <struct>  Information about volume
+%       vol          = <3Dimage> Output 3D volume
+%       info         = <struct>  Information about volume
 %
-%     Version 003 30-10-2012
+%     Version 003 30-10-2012 by YGuilhem, yoann.guilhem@esrf.fr
 %       Use tifflib for fast reading
 %       Some bugfixes
 %
@@ -37,9 +36,10 @@ function [vol, info] = gtTIFVolReader(filename, varargin)
 
 % Set default parameters and parse optional arguments
 params.newMethod = true;
-params.xrange = 'all';
-params.yrange = 'all';
-params.zrange = 'all';
+params.xrange = [];
+params.yrange = [];
+params.zrange = [];
+params.bbox = [];
 params.mode = 'single';
 params.filext = 'tif';
 params.digits = 4;
@@ -73,7 +73,6 @@ if ~exist('filename', 'var')
     end
 end
 
-
 % Get file parts and store the proper extension
 [fpath, fname, fext] = fileparts(filename);
 if any(strcmp(fext, {'.tif', '.tiff'}))
@@ -94,7 +93,7 @@ else
     fullFilenameFormat = fullfile(fpath, filenameFormat);
 
     % Check existence of input stack files
-    for idx=params.startindex:params.endindex
+    for idx = params.startindex:params.endindex
         sfilename = sprintf(fullFilenameFormat, idx);
         if ~exist(sfilename, 'file')
             gtError('gtTIFVolReader:wrong_file_name', ...
@@ -135,6 +134,20 @@ tifSizeZ = length(fileIndex);
 [fpath, fname, ~] = fileparts(fullFilename);
 fullFilenameFormat = fullfile(fpath, filenameFormat);
 
+% Check if we use ranges or bbox input
+if isempty(params.bbox)
+    if isempty(params.xrange), params.xrange = 'all'; end;
+    if isempty(params.yrange), params.yrange = 'all'; end;
+    if isempty(params.zrange), params.zrange = 'all'; end;
+elseif isempty([params.xrange params.yrange params.zrange])
+    params.xrange = params.bbox(1):params.bbox(4);
+    params.yrange = params.bbox(2):params.bbox(5);
+    params.zrange = params.bbox(3):params.bbox(6);
+else
+    gtError('gtTIFVolReader:wrong_range_input', ...
+        'You cannot use both bbox and [xyz]range options!');
+end
+
 % Check each dimension range
 fullRangeXY = true;
 if strcmp(params.xrange, 'all')
@@ -183,6 +196,9 @@ end
 info.volSizeX = volSizeX;
 info.volSizeY = volSizeY;
 info.volSizeZ = volSizeZ;
+info.tifSizeX = tifSizeX;
+info.tifSizeY = tifSizeY;
+info.tifSizeZ = tifSizeZ;
 info.bytespervoxel = tifInfo(1).SamplesPerPixel * tifInfo(1).BitsPerSample / 8;
 info.fpath = fpath;
 info.byteorder = tifInfo(1).ByteOrder(1);
diff --git a/zUtil_TIFF/gtTIFVolReaderWithInfo.m b/zUtil_TIFF/gtTIFVolReaderWithInfo.m
new file mode 100644
index 00000000..29f251fc
--- /dev/null
+++ b/zUtil_TIFF/gtTIFVolReaderWithInfo.m
@@ -0,0 +1,41 @@
+function [vol, info] = gtTIFVolReaderWithInfo(filename, varargin)
+% GTTIFVOLREADERWITHINFO  Read TIFF volume with the info (BBox and voxelsize).
+%
+%     [vol, info] = gtTIFVolReaderWithInfo(filename, varargin)
+%     -------------------------------------------------------------------------
+%
+%     INPUT:
+%       filename     = <string>  Path to TIFF file to write
+%                                it may be relative or absolute
+%                                if extension is missing, '.tif' is append
+%
+%     OPTIONAL INPUT -> see gtTIFVolReader
+%
+%     OUTPUT:
+%       vol        = <3Dimage> Output 3D volume
+%       info       = <struct>  Information about volume
+%
+%     Note:
+%       info file should be formatted as the following:
+%
+%       [bboxMinX, bboxMinY, bboxMinZ] [bboxMaxX, bboxMaxY, bboxMaxZ]
+%       voxelsize
+%
+%     Version 001 24-04-2013 by YGuilhem, yoann.guilhem@esrf.fr
+
+% Read TIFF file
+if isempty(varargin)
+    [vol, info] = gtTIFVolReader(filename);
+else
+    [vol, info] = gtTIFVolReader(filename, varargin);
+end
+
+% Extract path, basename and extension from file name
+[fpath, fname, fext] = fileparts(info.fname_final);
+
+% Read info from file
+infoFile = fullfile(fpath, [fname '.info']);
+info = gtTIFInfoReader(infoFile, info);
+
+end % end of function
+
diff --git a/zUtil_TIFF/gtTIFVolWriter.m b/zUtil_TIFF/gtTIFVolWriter.m
index 6cdc8590..f3fc2189 100644
--- a/zUtil_TIFF/gtTIFVolWriter.m
+++ b/zUtil_TIFF/gtTIFVolWriter.m
@@ -15,28 +15,27 @@ function gtTIFVolWriter(vol, filename, varargin)
 %                                number and the extension will be append.
 %
 %     OPTIONAL INPUT (varargin as a list of pairs, see parse_pv_pairs.m):
-%       'xrange'     = <range>   Index range of output in X direction
-%       'yrange'     = <range>               "            Y     "
-%       'zrange'     = <range>               "            Z     "
+%       'xrange'     = <int>     Index range of output in X direction {'all'}
+%       'yrange'     = <int>                 "            Y     "     {'all'}
+%       'zrange'     = <int>                 "            Z     "     {'all'}
+%       'bbox'       = <int>     Index range as bbox [Xi Yi Zi Xf Yf Zf]
 %
 %       'type'       = <string>  Force type of data written in the TIFF file
 %                                it can be 'uint8', 'uint16' or 'logical'
-%                                default is 'uint8'
+%                                default is detected from input volume class 
 %
-%       'compress'   = <string>  Compression mode, by default 'none', can be
-%                                'packbits', 'lzm', 'deflate', 'ccitt', 'fax3'
-%                                or 'fax4'
+%       'compress'   = <string>  Compression mode can be {'none'}, 'packbits',
+%                                'lzm', 'deflate', 'ccitt', 'fax3' or 'fax4'
 %
-%       'mode'       = <string>  Output type which is 'single' or 'stack'
-%                                default is a single TIFF file
-%       'digits'     = <int>     Number of digits in stack filenames
-%       'startindex' = <int>     Starting index for stack filenames
-%       'filext'     = <string>  Output TIFF file extension ('tif' or 'tiff')
-%                                default is 'tif'
-%       'newMethod'  = <bool>    Use new TIFF writing method (faster)
+%       'mode'       = <string>  Output type which is {'single'} or 'stack'
+%       'digits'     = <int>     Number of digits in stack filenames {4}
+%       'startindex' = <int>     Starting index for stack filenames {1}
+%       'filext'     = <string>  Output TIFF file extension {'tif'}
+%       'newMethod'  = <bool>    Use new TIFF writing method (faster) {true}
 %
-%     TODO :
-%     - RGB data output
+%     TODO:
+%       - RGB data output
+%       - float output
 %
 %     Version 003 30-10-2012 by YGuilhem, yoann.guilhem@esrf.fr
 %       Use tifflib for fast reading
@@ -50,9 +49,10 @@ function gtTIFVolWriter(vol, filename, varargin)
 
 % Set default parameters and parse optional arguments
 params.newMethod = true;
-params.xrange = 'all';
-params.yrange = 'all';
-params.zrange = 'all';
+params.xrange = [];
+params.yrange = [];
+params.zrange = [];
+params.bbox = [];
 params.type = '';
 params.compress = 'none';
 params.mode = 'single';
@@ -67,6 +67,20 @@ if params.newMethod && ~exist('tifflib', 'file')
     params.newMethod = false;
 end
 
+% Check if we use ranges or bbox input
+if isempty(params.bbox)
+    if isempty(params.xrange), params.xrange = 'all'; end;
+    if isempty(params.yrange), params.yrange = 'all'; end;
+    if isempty(params.zrange), params.zrange = 'all'; end;
+elseif isempty([params.xrange params.yrange params.zrange])
+    params.xrange = params.bbox(1):params.bbox(4);
+    params.yrange = params.bbox(2):params.bbox(5);
+    params.zrange = params.bbox(3):params.bbox(6);
+else
+    gtError('gtTIFVolWriter:wrong_range_input', ...
+        'You cannot use both bbox and [xyz]range options!');
+end
+
 % Translating range parameters
 if strcmp(params.xrange, 'all')
     rangeX = 1:size(vol, 1);
@@ -111,7 +125,7 @@ else
         rescale = 0;
     case 'uint8'
         rescale = 255;
-    otherwise
+    case 'uint16'
         rescale = 65535;
     end
 end
@@ -211,7 +225,7 @@ if strcmpi(params.mode, 'single')
     % Writing volume in TIFF file
     if params.newMethod
         tif = Tiff(filename, 'a');
-        for iz=1:length(rangeZ)
+        for iz = 1:length(rangeZ)
             tif.setTag(tifTag);
             tif.write(outVol(rangeX, rangeY, rangeZ(iz))');
             tif.writeDirectory();
@@ -219,7 +233,7 @@ if strcmpi(params.mode, 'single')
         tif.close();
     else
         % Old method
-        for iz=1:length(rangeZ)
+        for iz = 1:length(rangeZ)
             imwrite(outVol(rangeX(1):rangeX(end), rangeY(1):rangeY(end), ...
                 rangeZ(iz))', ...
                 filename, 'tif', 'Compression', params.compress, ...
@@ -266,7 +280,7 @@ elseif strcmpi(params.mode, 'stack')
 
     % Writing volume in TIFF stack files
     if params.newMethod
-        for iz=1:length(rangeZ)
+        for iz = 1:length(rangeZ)
             outFile = sprintf(filenameFMT, iz+offset);
             tif = Tiff(outFile, 'w');
             tif.setTag(tifTag);
@@ -275,7 +289,7 @@ elseif strcmpi(params.mode, 'stack')
         end
     else
         % Old method
-        for iz=1:length(rangeZ)
+        for iz = 1:length(rangeZ)
             outFile = sprintf(filenameFMT, iz+offset);
             imwrite(outVol(rangeX, rangeY, rangeZ(iz))', outFile, 'tif', ...
                     'Compression', params.compress, 'writemode', 'overwrite');
@@ -284,3 +298,4 @@ elseif strcmpi(params.mode, 'stack')
 end
 
 end % end of function
+
-- 
GitLab