title: How can I speed up rotating a huge TIFF by 90 degrees
body: <p>I'm processing huge TIFF images (grayscale, 8 or 16 bit, up to 4 GB) to be used as high resolution input data for a machine. Each image needs to be rotated by 90 degrees (clockwise). The input TIFF can be LZW or uncompressed, the output may be uncompressed. </p>
  
  <p>So far I implemented my own TIFF reader class in Objective C (including LZW decompression) which is able to handle huge files and does some caching in memory as well. At the moment the TIFF reader class is used for visualization and measurement inside the image and it performs quite good.</p>
  
  <p>For my latest challenge, rotating a TIFF, I need a new approach, because the current implementation is VERY slow. Even for a "medium" sized TIFF (30.000 x 4.000) it takes approx. 30 minutes to rotate the image. At the moment I loop through all pixels and pick the one with reversed x and y coordinates, put all of them into a buffer and write the buffer to disk as soon as one line is complete. The main problem is the reading from the TIFF, since data is organized in strips and not guaranteed to be linearly distributed inside the file (and in case of LZW compressed strips, nothing is linear as well).</p>
  
  <p>I profiled my software and found out that most of the time is spent in copying memory blocks (memmove) and decided to bypass the caching inside my reader class for the rotation. Now the whole process is about 5% faster, which isn't too much, and all of the time is now spent inside fread(). I assume that at least my cache performs almost as well as the system's fread() cache.</p>
  
  <p>Another test using Image Magick with the same 30.000 x 4.000 file took only around 10 seconds to complete. AFAIK Image Magick reads the whole file into memory, processes it in memory and then writes back to disk. This works well up to a few hundred megabytes of image data.</p>
  
  <p>What I'm looking for is some kind of "meta optimization", like another approach for handling the pixel data. Is there another strategy than swapping pixels one by one (and needing to read from file locations far away from each other)? Should I create some intermediate file to speed up the process? Any suggestions welcome.</p>