Rotate image by 180 degrees (libtiff code)
Fastish inplace rotation of an image by 180 degrees:
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:
#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])); }