{"id":867,"date":"2013-08-07T07:05:36","date_gmt":"2013-08-07T11:05:36","guid":{"rendered":"https:\/\/blogs.mathworks.com\/steve\/?p=867"},"modified":"2019-11-01T09:22:08","modified_gmt":"2019-11-01T13:22:08","slug":"tiff-bigtiff-and-blockproc","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/steve\/2013\/08\/07\/tiff-bigtiff-and-blockproc\/","title":{"rendered":"TIFF, BigTIFF, and blockproc"},"content":{"rendered":"<div class=\"content\"><!--introduction--><p><i>I'd like to welcome back guest blogger Ashish Uthama for today's post. Ashish, a developer on the Image Processing Toolbox team, posted here previously about <a href=\"https:\/\/blogs.mathworks.com\/steve\/2010\/11\/09\/the-mystery-of-the-failing-tiff-append-loop\/\">the mystery of the failing TIFF append loop<\/a>.<\/i><\/p><!--\/introduction--><h3>Contents<\/h3><div><ul><li><a href=\"#284f489f-9492-475d-a5c6-aa0f2ae776c4\">Brief introduction to the TIFF format<\/a><\/li><li><a href=\"#677adf29-05ab-4f85-92df-12263063154b\">Enter BigTIFF<\/a><\/li><li><a href=\"#c938f189-9397-491e-93ee-54af3116ccd1\">BigTIFF support in MATLAB<\/a><\/li><li><a href=\"#da8f951f-40c8-4d87-aec3-fee122023234\">Using BigTIFF with BLOCKPROC (Image Processing Toolbox)<\/a><\/li><\/ul><\/div><h4>Brief introduction to the TIFF format<a name=\"284f489f-9492-475d-a5c6-aa0f2ae776c4\"><\/a><\/h4><p>A TIFF file is, well, a <a href=\"http:\/\/en.wikipedia.org\/wiki\/Tagged_Image_File_Format\">Tagged Image File Format<\/a> (TIFF). As the name implies, the file itself consists of a whole bunch of <a href=\"http:\/\/www.awaresystems.be\/imaging\/tiff\/faq.html#q1\">'tags'<\/a> and corresponding values. For example, all TIFF files are expected to have the ImageWidth and ImageLength tags, whose values are the width and length (height) of the image stored within.<\/p><p>A core feature of this format lies in how image data is organized in a physical file. TIFF allows for the image data to be stored in chunks as either 'Tiles' or 'Strips'. You could think of a strip as a tile whose width is the same as the image. The format stores offsets for each of these strips or tiles in an image header. This allows for efficient random access of any chunk in the image. The original TIFF format specification calls for use of 32 bit file offset values. I guess you can imagine where I am going with that bit of information. 32 bits implies a maximum value of 2^32 for any offset. Note that these are offsets from the very beginning of the file. In effect, the 32 bit requirement limits the size of the largest possible TIFF file to be under 4 gigabytes. This was fine for a long time (The earliest TIFF release was in 1986), but we now have more data producers hitting this limit.<\/p><h4>Enter BigTIFF<a name=\"677adf29-05ab-4f85-92df-12263063154b\"><\/a><\/h4><p>The libtiff community, a loosely organized collection of volunteer software developers, maintains and develops the LibTIFF library. LibTIFF implements routines to manipulate TIFF files. Since version 4.0.0 of LibTIFF, they have included a variant of the TIFF format which uses 64 bits for the offsets instead of 32 bits. As you can imagine, this allows for really big TIFF files. This variant is appropriately called <a href=\"http:\/\/www.awaresystems.be\/imaging\/tiff\/bigtiff.html\">BigTIFF<\/a> . Do note that this underlying change causes BigTIFF to an incompatible variant to the 32 bit offset TIFF format (now called the classic format). The first stable version of libtiff with BigTIFF support came out just in time for us to be able to qualify and test it to go out with MATLAB R2012b.<\/p><h4>BigTIFF support in MATLAB<a name=\"c938f189-9397-491e-93ee-54af3116ccd1\"><\/a><\/h4><p>As I mentioned in the introduction, TIFF files have tags and values. This approach gives the format a lot of flexibility in the type of data it can hold, and yes, with great flexibility comes great complexity.<\/p><p>Reading BigTIFF file in MATLAB is no different from reading classic (32bit offset) version TIFF files. <tt>imread<\/tt> and all its <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/imread.html#f25-721031\">TIFF related options<\/a> work with BigTIFF. With BigTIFF files, the most relevant option is the 'PixelRegion' parameter. If a BigTIFF image file is too large to fit in system memory, you could use this parameter to load a smaller part of the image. <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/imwrite.html\"><tt>imwrite<\/tt><\/a> can easily write out classic TIFF files. However, writing out BigTIFF files is a bit more involved. The key assumption with using <tt>imwrite<\/tt> is that the entire image data is available as a matrix in memory, something not necessarily true with BigTIFF. Tiff images can be complex and there are hundreds of possible combinations of the various tag values. In addition, the format enforces rules (see <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/import_export\/exporting-to-images.html#br_c_iz-7\">Tables 2, 3, 4 and 5<\/a>) for legal combinations of tag values.<\/p><p>MATLAB provides a gateway to the LibTIFF library routines through the <a title=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/tiffclass.html (link no longer works)\"><tt>Tiff<\/tt> class<\/a>. This interface supports over <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/import_export\/exporting-to-images.html#br_c_iz-6\">60 tags<\/a>, allowing MATLAB users to <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/import_export\/exporting-to-images.html#br_c_iz-1\">work<\/a> with a wide range of TIFF files. Moreover, this interface also supports working with BigTIFF files. Here is a code snippet which uses the <tt>Tiff<\/tt> class to write a (albeit small) BigTIFF file:<\/p><pre class=\"codeinput\">imdata = imread(<span class=\"string\">'example.tif'<\/span>);\r\n<span class=\"comment\">% 'w'  will create a classic TIFF file<\/span>\r\n<span class=\"comment\">% 'w8' will create a BigTIFF file<\/span>\r\n<span class=\"comment\">% This option is the only differentiator when writing to these two formats.<\/span>\r\nbt     = Tiff(<span class=\"string\">'myfile.tif'<\/span>,<span class=\"string\">'w8'<\/span>);\r\n<\/pre><p>More information on the tags used below is <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/import_export\/exporting-to-images.html#br_c_iz-6\">here<\/a>.<\/p><pre class=\"codeinput\">tags.ImageLength         = size(imdata,1);\r\ntags.ImageWidth          = size(imdata,2);\r\ntags.Photometric         = Tiff.Photometric.RGB;\r\ntags.BitsPerSample       = 8;\r\ntags.SamplesPerPixel     = size(imdata,3);\r\ntags.TileWidth           = 128;\r\ntags.TileLength          = 128;\r\ntags.Compression         = Tiff.Compression.JPEG;\r\ntags.PlanarConfiguration = Tiff.PlanarConfiguration.Chunky;\r\ntags.Software            = <span class=\"string\">'MATLAB'<\/span>;\r\n\r\nsetTag(bt, tags);\r\nwrite(bt,  imdata);\r\nclose(bt);\r\n<\/pre><h4>Using BigTIFF with BLOCKPROC (Image Processing Toolbox)<a name=\"da8f951f-40c8-4d87-aec3-fee122023234\"><\/a><\/h4><p>The ability to store and retrieve parts of the image as tiles makes TIFF images a perfect fit for the Image Processing Toolbox function <a href=\"https:\/\/www.mathworks.com\/help\/images\/ref\/blockproc.html\"><tt>blockproc<\/tt><\/a>. <tt>blockproc<\/tt> was designed to handle large data and also has a parallel mode to take advantage of the Parallel Computing Toolbox capability to run on large clusters. Read support for TIFF files is provided by <tt>imread<\/tt> under the hood, hence <tt>blockproc<\/tt> inherits the ability to read BigTIFF files out of the box. However, write support is limited to classic TIFF files. To enable <tt>blockproc<\/tt> to write out a BigTIFF file, we need a custom image adapter. Brendan <a href=\"https:\/\/blogs.mathworks.com\/steve\/2011\/09\/23\/dealing-with-really-big-images-image-adapters\/\">blogged<\/a> about this here sometime back. I put together a simple BigTIFF writer image adapter based on his blog post. It is also available on the <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/42086-bigtiffwriter\">File Exchange<\/a> for download.<\/p><pre class=\"codeinput\">type <span class=\"string\">bigTiffWriter.m<\/span>\r\n<\/pre><pre class=\"codeoutput\">\r\nclassdef bigTiffWriter &lt; ImageAdapter\r\n    %BIGTIFFWRITER - A basic image adapter to write Big TIFF files.\r\n    %\r\n    % A simple ImageAdapter class implementing a Tiff writer ImageAdapter\r\n    % object for use with BLOCKPROC. \r\n    % - Tile dimensions must be multiples of 16.\r\n    % - Only uint8, RGB input image data is supported.\r\n    %\r\n    % Based on \"Working with Data in Unsupported Formats\"\r\n    % https:\/\/www.mathworks.com\/help\/toolbox\/images\/f7-12726.html#bse_q4y-1\r\n    %\r\n    % Example:\r\n    %    %%\r\n    %    % Set file names and obtain size information from input file.\r\n    %    inFile        = 'example.tif';\r\n    %    inFileInfo    = imfinfo(inFile);\r\n    %    outFile       = 'out.tif';\r\n    %    %%\r\n    %    % Create an output TIFF file with tile size of 128x128 \r\n    %    tileSize      = [128, 128]; % has to be a multiple of 16.\r\n    %    outFileWriter = bigTiffWriter(outFile, inFileInfo(1).Height, inFileInfo(2).Width, tileSize(1), tileSize(2));\r\n    %    %%\r\n    %    % Now call blockproc to rearrange the color channels.\r\n    %    blockproc(inFile, tileSize, @(b) flipdim(b.data,3), 'Destination', outFileWriter);\r\n    %    outFileWriter.close();\r\n    %    imshowpair(imread(inFile), imread(outFile),'montage');\r\n    %\r\n    % See also: blockproc, Tiff, Tiff\/writeEncodedTile\r\n    %\r\n    \r\n    %   Copyright 2013 The MathWorks, Inc.\r\n    \r\n    properties(GetAccess = public, SetAccess = private)        \r\n        Filename;        \r\n        TiffObject;\r\n        TileLength;\r\n        TileWidth;        \r\n    end\r\n    \r\n    methods\r\n        \r\n        function obj = bigTiffWriter(fname, imageLength, imageWidth, tileLength, tileWidth)\r\n            % Constructor\r\n            \r\n            validateattributes(fname,       {'char'},   {'row'});\r\n            validateattributes(imageLength, {'numeric'},{'scalar'});\r\n            validateattributes(imageWidth,  {'numeric'},{'scalar'});\r\n            validateattributes(tileLength,  {'numeric'},{'scalar'});\r\n            validateattributes(tileWidth,   {'numeric'},{'scalar'});\r\n            \r\n            if(mod(tileLength,16)~=0 || mod(tileWidth,16)~=0)\r\n                error('bigTiffWriter:invalidTileSize',...\r\n                    'Tile size must be a multiple of 16');\r\n            end\r\n            \r\n            obj.Filename   = fname;\r\n            obj.ImageSize  = [imageLength, imageWidth, 1];\r\n            obj.TileLength = tileLength;\r\n            obj.TileWidth  = tileWidth;\r\n            \r\n            % Create the Tiff object.\r\n            obj.TiffObject = Tiff(obj.Filename, 'w8');\r\n            \r\n            % Setup the tiff file properties\r\n            % See \"Exporting Image Data and Metadata to TIFF files\r\n            % https:\/\/www.mathworks.com\/help\/techdoc\/import_export\/f5-123068.html#br_c_iz-1\r\n            %\r\n            obj.TiffObject.setTag('ImageLength',   obj.ImageSize(1));\r\n            obj.TiffObject.setTag('ImageWidth',    obj.ImageSize(2));\r\n            obj.TiffObject.setTag('TileLength',    obj.TileLength);\r\n            obj.TiffObject.setTag('TileWidth',     obj.TileWidth);\r\n            obj.TiffObject.setTag('Photometric',   Tiff.Photometric.RGB);\r\n            obj.TiffObject.setTag('BitsPerSample', 8);\r\n            obj.TiffObject.setTag('SampleFormat',  Tiff.SampleFormat.UInt);\r\n            obj.TiffObject.setTag('SamplesPerPixel', 3);\r\n            obj.TiffObject.setTag('PlanarConfiguration', Tiff.PlanarConfiguration.Chunky);           \r\n        end\r\n        \r\n        \r\n        function [] = writeRegion(obj, region_start, region_data)\r\n            % Write a block of data to the tiff file.\r\n            \r\n            % Map region_start to a tile number.\r\n            tile_number = obj.TiffObject.computeTile(region_start);\r\n            \r\n            % If region_data is greater than tile size, this function\r\n            % warns, else it will silently pad with 0s.\r\n            obj.TiffObject.writeEncodedTile(tile_number, region_data);\r\n            \r\n        end\r\n        \r\n        \r\n        function data = readRegion(~,~,~) %#ok&lt;STOUT&gt;\r\n            % Not implemented.\r\n            error('bigTiffWriter:noReadSupport',...\r\n                'Read support is not implemented.');\r\n        end\r\n        \r\n        \r\n        function close(obj)\r\n            % Close the tiff file\r\n            obj.TiffObject.close();\r\n        end\r\n        \r\n    end    \r\nend\r\n<\/pre><p>Let us run the included example:<\/p><p>Set file names and obtain size information from input file.<\/p><pre class=\"codeinput\">inFile        = <span class=\"string\">'example.tif'<\/span>;\r\ninFileInfo    = imfinfo(inFile);\r\noutFile       = <span class=\"string\">'out.tif'<\/span>;\r\n<\/pre><p>Create an output TIFF file with tile size of 128x128<\/p><pre class=\"codeinput\">tileSize      = [128, 128]; <span class=\"comment\">% has to be a multiple of 16.<\/span>\r\noutFileWriter = bigTiffWriter(outFile, inFileInfo(1).Height, inFileInfo(2).Width, tileSize(1), tileSize(2));\r\n<\/pre><p>Now call blockproc to rearrange the color channels.<\/p><pre class=\"codeinput\">blockproc(inFile, tileSize, @(b) flipdim(b.data,3), <span class=\"string\">'Destination'<\/span>, outFileWriter);\r\noutFileWriter.close();\r\nimshowpair(imread(inFile), imread(outFile),<span class=\"string\">'montage'<\/span>);\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/2013\/BigTIFF_BlogPost_01.jpg\" alt=\"\"> <p>This adapter can serve as a starting point to write more complicated writer adapters for your particular tag combination of the Tiff format. Do you work with large image data? Do you, or would you use BigTIFF for your work? Do let us know!<\/p><script language=\"JavaScript\"> <!-- \r\n    function grabCode_d8d64bbafaa243feb965c785c3f26f3d() {\r\n        \/\/ Remember the title so we can use it in the new page\r\n        title = document.title;\r\n\r\n        \/\/ Break up these strings so that their presence\r\n        \/\/ in the Javascript doesn't mess up the search for\r\n        \/\/ the MATLAB code.\r\n        t1='d8d64bbafaa243feb965c785c3f26f3d ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' d8d64bbafaa243feb965c785c3f26f3d';\r\n    \r\n        b=document.getElementsByTagName('body')[0];\r\n        i1=b.innerHTML.indexOf(t1)+t1.length;\r\n        i2=b.innerHTML.indexOf(t2);\r\n \r\n        code_string = b.innerHTML.substring(i1, i2);\r\n        code_string = code_string.replace(\/REPLACE_WITH_DASH_DASH\/g,'--');\r\n\r\n        \/\/ Use \/x3C\/g instead of the less-than character to avoid errors \r\n        \/\/ in the XML parser.\r\n        \/\/ Use '\\x26#60;' instead of '<' so that the XML parser\r\n        \/\/ doesn't go ahead and substitute the less-than character. \r\n        code_string = code_string.replace(\/\\x3C\/g, '\\x26#60;');\r\n\r\n        copyright = 'Copyright 2013 The MathWorks, Inc.';\r\n\r\n        w = window.open();\r\n        d = w.document;\r\n        d.write('<pre>\\n');\r\n        d.write(code_string);\r\n\r\n        \/\/ Add copyright line at the bottom if specified.\r\n        if (copyright.length > 0) {\r\n            d.writeln('');\r\n            d.writeln('%%');\r\n            if (copyright.length > 0) {\r\n                d.writeln('% _' + copyright + '_');\r\n            }\r\n        }\r\n\r\n        d.write('<\/pre>\\n');\r\n\r\n        d.title = title + ' (MATLAB code)';\r\n        d.close();\r\n    }   \r\n     --> <\/script><p style=\"text-align: right; font-size: xx-small; font-weight:lighter;   font-style: italic; color: gray\"><br><a href=\"javascript:grabCode_d8d64bbafaa243feb965c785c3f26f3d()\"><span style=\"font-size: x-small;        font-style: italic;\">Get \r\n      the MATLAB code <noscript>(requires JavaScript)<\/noscript><\/span><\/a><br><br>\r\n      Published with MATLAB&reg; R2013a<br><\/p><p class=\"footer\"><br>\r\n      Published with MATLAB&reg; R2013a<br><\/p><\/div><!--\r\nd8d64bbafaa243feb965c785c3f26f3d ##### SOURCE BEGIN #####\r\n%%\r\n% _I'd like to welcome back guest blogger Ashish Uthama for today's post.\r\n% Ashish, a developer on the Image Processing Toolbox team, posted here\r\n% previously about\r\n% <https:\/\/blogs.mathworks.com\/steve\/2010\/11\/09\/the-mystery-of-the-failing-tiff-append-loop\/\r\n% the mystery of the failing TIFF append loop>._\r\n\r\n%% Brief introduction to the TIFF format\r\n%\r\n% A TIFF file is, well, a\r\n% <http:\/\/en.wikipedia.org\/wiki\/Tagged_Image_File_Format Tagged Image File\r\n% Format> (TIFF). As the name implies, the file itself consists of a whole\r\n% bunch of <http:\/\/www.awaresystems.be\/imaging\/tiff\/faq.html#q1 'tags'> and\r\n% corresponding values. For example, all TIFF files are expected to have\r\n% the ImageWidth and ImageLength tags, whose values are the width and\r\n% length (height) of the image stored within.\r\n%\r\n%\r\n% A core feature of this format lies in how image data is organized in a\r\n% physical file. TIFF allows for the image data to be stored in chunks as\r\n% either 'Tiles' or 'Strips'. You could think of a strip as a tile whose\r\n% width is the same as the image. The format stores offsets for each of\r\n% these strips or tiles in an image header. This allows for efficient\r\n% random access of any chunk in the image. The original TIFF format\r\n% specification calls for use of 32 bit file offset values. I guess you can\r\n% imagine where I am going with that bit of information. 32 bits implies a\r\n% maximum value of 2^32 for any offset. Note that these are offsets from\r\n% the very beginning of the file. In effect, the 32 bit requirement limits\r\n% the size of the largest possible TIFF file to be under 4 gigabytes. This\r\n% was fine for a long time (The earliest TIFF release was in 1986), but we\r\n% now have more data producers hitting this limit.\r\n\r\n%% Enter BigTIFF\r\n%\r\n% The <http:\/\/www.remotesensing.org\/libtiff\/ libtiff> community, a loosely\r\n% organized collection of volunteer software developers, maintains and\r\n% develops the LibTIFF library. LibTIFF implements routines to manipulate\r\n% TIFF files. Since version 4.0.0 of LibTIFF, they have\r\n% included a variant of the TIFF format which uses 64 bits for the offsets\r\n% instead of 32 bits. As you can imagine, this allows for really big TIFF\r\n% files. This variant is appropriately called\r\n% <http:\/\/www.awaresystems.be\/imaging\/tiff\/bigtiff.html BigTIFF> . Do note\r\n% that this underlying change causes BigTIFF to an incompatible variant to\r\n% the 32 bit offset TIFF format (now called the classic format). The first\r\n% stable version of libtiff with BigTIFF support came out just in time for\r\n% us to be able to qualify and test it to go out with MATLAB R2012b.\r\n\r\n%% BigTIFF support in MATLAB\r\n%\r\n% As I mentioned in the introduction, TIFF files have tags and values.\r\n% This approach gives the format a lot of flexibility in the type of data\r\n% it can hold, and yes, with great flexibility comes great complexity.\r\n%\r\n% Reading BigTIFF file in MATLAB is no different from reading classic\r\n% (32bit offset) version TIFF files. |imread| and all its\r\n% <https:\/\/www.mathworks.com\/help\/matlab\/ref\/imread.html#f25-721031 TIFF\r\n% related options> work with BigTIFF. With BigTIFF files, the most relevant\r\n% option is the 'PixelRegion' parameter. If a BigTIFF image file is too\r\n% large to fit in system memory, you could use this parameter to load a\r\n% smaller part of the image.\r\n% <https:\/\/www.mathworks.com\/help\/matlab\/ref\/imwrite.html |imwrite|> can\r\n% easily write out classic TIFF files. However, writing out BigTIFF files\r\n% is a bit more involved. The key assumption with using |imwrite| is that\r\n% the entire image data is available as a matrix in memory, something not\r\n% necessarily true with BigTIFF. Tiff images can be complex and there are\r\n% hundreds of possible combinations of the various tag values. In addition,\r\n% the format enforces rules (see\r\n% <https:\/\/www.mathworks.com\/help\/matlab\/import_export\/exporting-to-images.html#br_c_iz-7\r\n% Tables 2, 3, 4 and 5>) for legal combinations of tag values.\r\n%\r\n% MATLAB provides a gateway to the LibTIFF library routines through the\r\n% <https:\/\/www.mathworks.com\/help\/matlab\/ref\/tiffclass.html |Tiff| class>.\r\n% This interface supports over\r\n% <https:\/\/www.mathworks.com\/help\/matlab\/import_export\/exporting-to-images.html#br_c_iz-6\r\n% 60 tags>, allowing MATLAB users to\r\n% <https:\/\/www.mathworks.com\/help\/matlab\/import_export\/exporting-to-images.html#br_c_iz-1\r\n% work> with a wide range of TIFF files. Moreover, this interface also\r\n% supports working with BigTIFF files. Here is a code snippet which uses\r\n% the |Tiff| class to write a (albeit small) BigTIFF file:\r\n%\r\nimdata = imread('example.tif');\r\n% 'w'  will create a classic TIFF file\r\n% 'w8' will create a BigTIFF file\r\n% This option is the only differentiator when writing to these two formats.\r\nbt     = Tiff('myfile.tif','w8');\r\n%%\r\n% More information on the tags used below is\r\n% <https:\/\/www.mathworks.com\/help\/matlab\/import_export\/exporting-to-images.html#br_c_iz-6\r\n% here>.\r\ntags.ImageLength         = size(imdata,1);\r\ntags.ImageWidth          = size(imdata,2);\r\ntags.Photometric         = Tiff.Photometric.RGB;\r\ntags.BitsPerSample       = 8;\r\ntags.SamplesPerPixel     = size(imdata,3);\r\ntags.TileWidth           = 128;\r\ntags.TileLength          = 128;\r\ntags.Compression         = Tiff.Compression.JPEG;\r\ntags.PlanarConfiguration = Tiff.PlanarConfiguration.Chunky;\r\ntags.Software            = 'MATLAB';\r\n\r\nsetTag(bt, tags);\r\nwrite(bt,  imdata);\r\nclose(bt);\r\n\r\n%% Using BigTIFF with BLOCKPROC (Image Processing Toolbox)\r\n%\r\n% The ability to store and retrieve parts of the image as tiles makes TIFF\r\n% images a perfect fit for the Image Processing Toolbox function\r\n% <https:\/\/www.mathworks.com\/help\/images\/ref\/blockproc.html |blockproc|>.\r\n% |blockproc| was designed to handle large data and also has a parallel\r\n% mode to take advantage of the Parallel Computing Toolbox capability to\r\n% run on large clusters. Read support for TIFF files is provided by\r\n% |imread| under the hood, hence |blockproc| inherits the ability to read\r\n% BigTIFF files out of the box. However, write support is limited to\r\n% classic TIFF files. To enable |blockproc| to write out a BigTIFF file, we\r\n% need a custom image adapter. Brendan\r\n% <https:\/\/blogs.mathworks.com\/steve\/2011\/09\/23\/dealing-with-really-big-images-image-adapters\/\r\n% blogged> about this here sometime back. I put together a simple BigTIFF\r\n% writer image adapter based on his blog post. It is also available on the\r\n% <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/42086-bigtiffwriter\r\n% File Exchange> for download.\r\n\r\ntype bigTiffWriter.m\r\n%%\r\n% Let us run the included example:\r\n%%\r\n% Set file names and obtain size information from input file.\r\ninFile        = 'example.tif';\r\ninFileInfo    = imfinfo(inFile);\r\noutFile       = 'out.tif';\r\n%%\r\n% Create an output TIFF file with tile size of 128x128\r\ntileSize      = [128, 128]; % has to be a multiple of 16.\r\noutFileWriter = bigTiffWriter(outFile, inFileInfo(1).Height, inFileInfo(2).Width, tileSize(1), tileSize(2));\r\n%%\r\n% Now call blockproc to rearrange the color channels.\r\nblockproc(inFile, tileSize, @(b) flipdim(b.data,3), 'Destination', outFileWriter);\r\noutFileWriter.close();\r\nimshowpair(imread(inFile), imread(outFile),'montage');\r\n\r\n%%\r\n% This adapter can serve as a starting point to write more complicated\r\n% writer adapters for your particular tag combination of the Tiff format.\r\n% Do you work with large image data? Do you, or would you use BigTIFF for\r\n% your work? Do let us know!\r\n\r\n\r\n\r\n##### SOURCE END ##### d8d64bbafaa243feb965c785c3f26f3d\r\n-->","protected":false},"excerpt":{"rendered":"<div class=\"overview-image\"><img decoding=\"async\"  class=\"img-responsive\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/2013\/BigTIFF_BlogPost_01.jpg\" onError=\"this.style.display ='none';\" \/><\/div><!--introduction--><p><i>I'd like to welcome back guest blogger Ashish Uthama for today's post. Ashish, a developer on the Image Processing Toolbox team, posted here previously about <a href=\"https:\/\/blogs.mathworks.com\/steve\/2010\/11\/09\/the-mystery-of-the-failing-tiff-append-loop\/\">the mystery of the failing TIFF append loop<\/a>.<\/i>... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/steve\/2013\/08\/07\/tiff-bigtiff-and-blockproc\/\">read more >><\/a><\/p>","protected":false},"author":42,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[711,278,1021,332,76,867,388,683,1019,1017],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/867"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/users\/42"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/comments?post=867"}],"version-history":[{"count":4,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/867\/revisions"}],"predecessor-version":[{"id":2509,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/867\/revisions\/2509"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/media?parent=867"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/categories?post=867"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/tags?post=867"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}