Rotate image by 180 degrees (libtiff code)

Fastish inplace rotation of an image by 180 degrees:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void rotate180() {
 
  size_t h;
  if((m_height%2) == 1) {
    h = (m_height/2)-1;
    size_t ymid = ((m_height-1)/2);
 
    for(size_t x=0;x<(m_width/2);x++) {
      swap_pixel(x,ymid,(m_width-x-1),ymid);
    }
 
  } else h = (m_height/2)-1;
  for(size_t x=0;x<m_width;x++) {
    for(size_t y=0;y<=h;y++) {
      swap_pixel(x,y,m_width-x-1,m_height-y-1);
    }
  }
}

You need to provide image get and set, and swap_pixel. Complete example below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#include "tiffio.h"
#include <iostream>
#include <math.h>
#include <vector>
#include <map>
#include <sys/stat.h>
#include <sys/types.h>
#include <sstream>
#include <stdexcept>
 
#define TIFFSetR(pixel, x) ((unsigned char *)pixel)[0] = x
#define TIFFSetG(pixel, x) ((unsigned char *)pixel)[1] = x
#define TIFFSetB(pixel, x) ((unsigned char *)pixel)[2] = x
#define TIFFSetA(pixel, x) ((unsigned char *)pixel)[3] = x
 
 
class BadConversion : public std::runtime_error {
public:
 BadConversion(const std::string& s)
      : std::runtime_error(s) {}
};
 
template<class _type>
inline std::string stringify(_type x)
{
  std::ostringstream o;
  if (!(o << std::fixed << x))
    throw BadConversion("stringify()");
  return o.str();
}
 
using namespace std;
 
class Image {
 
public:
 
  Image() {
  }
 
  enum fragment_type { frag_type_arrow, frag_type_rectange } ;
 
  void load_tiff(string input_filename) {
 
    m_image_data.clear();
 
    TIFF* tif = TIFFOpen(input_filename.c_str(), "r");
    if (tif) {
      uint32 w, h;
      size_t npixels;
      uint32* raster;
 
      TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w);
      TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h);
      npixels = w * h;
      m_width = w;
      m_height = h;
 
      raster = (uint32*) _TIFFmalloc(npixels * sizeof (uint32));
      if (raster != NULL) {
  if (TIFFReadRGBAImageOriented(tif, w, h, raster,ORIENTATION_TOPLEFT, 0)) {
    for(size_t n=0;n<npixels;n++) m_image_data.push_back(raster[n]);
  }
  _TIFFfree(raster);
      }
      TIFFClose(tif);
    }
  }
 
  void save_tiff_rgb(string output_filename) {
    TIFF *output_image;
 
    // Open the TIFF file
    if((output_image = TIFFOpen(output_filename.c_str(), "w")) == NULL){
      cerr << "Unable to write tif file: " << output_filename << endl;
    }
 
    // We need to set some values for basic tags before we can add any data
    TIFFSetField(output_image, TIFFTAG_IMAGEWIDTH, m_width);
    TIFFSetField(output_image, TIFFTAG_IMAGELENGTH, m_height);
    TIFFSetField(output_image, TIFFTAG_BITSPERSAMPLE, 8);
    TIFFSetField(output_image, TIFFTAG_SAMPLESPERPIXEL, 4);
    TIFFSetField(output_image, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
 
    TIFFSetField(output_image, TIFFTAG_COMPRESSION, COMPRESSION_DEFLATE);
    TIFFSetField(output_image, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
 
    // Write the information to the file
    TIFFWriteEncodedStrip(output_image, 0, &m_image_data[0], m_width*m_height * 4);
 
    // Close the file
    TIFFClose(output_image);
  }
 
  bool is_on_image(size_t x,size_t y) {
    if((x < m_width) && (y < m_height)) return true;
    return false;
  }
 
  uint32_t get(size_t x,size_t y) {
    return m_image_data[(y*m_width)+x];
  }
 
  void set(size_t x,size_t y,uint32_t value) {
    m_image_data[(y*m_width)+x] = value;
  }
 
  void swap_pixel(size_t x1,size_t y1,
                  size_t x2,size_t y2) {
 
    uint32_t t = get(x1,y1);
    set(x1,y1,get(x2,y2));
    set(x2,y2,t);
  }
 
  // Inplace 180 degree rotation.
  void rotate180() {
 
    size_t h;
    if((m_height%2) == 1) {
      h = (m_height/2)-1;
      size_t ymid = ((m_height-1)/2);
 
      for(size_t x=0;x<(m_width/2);x++) {
        swap_pixel(x,ymid,(m_width-x-1),ymid);
      }
 
    } else h = (m_height/2)-1;
    for(size_t x=0;x<m_width;x++) {
      for(size_t y=0;y<=h;y++) {
        swap_pixel(x,y,m_width-x-1,m_height-y-1);
      }
    }
  }
 
  vector<uint32_t> m_image_data;
  size_t m_width;
  size_t m_height;
};
 
int main(int argc, char* argv[]) {
 
  Image i;
  i.load_tiff(argv[1]);
  i.rotate180();
  i.save_tiff_rgb(string(argv[2]));
}

Leave a Reply