{"id":557,"date":"2011-11-01T21:59:47","date_gmt":"2011-11-01T21:59:47","guid":{"rendered":"http:\/\/41j.com\/blog\/?p=557"},"modified":"2011-11-01T22:44:00","modified_gmt":"2011-11-01T22:44:00","slug":"rotate-image-by-180-degrees-libtiff-code","status":"publish","type":"post","link":"https:\/\/41j.com\/blog\/2011\/11\/rotate-image-by-180-degrees-libtiff-code\/","title":{"rendered":"Rotate image by 180 degrees (libtiff code)"},"content":{"rendered":"<p>Fastish inplace rotation of an image by 180 degrees:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\n  void rotate180() {\r\n\r\n    size_t h;\r\n    if((m_height%2) == 1) {\r\n      h = (m_height\/2)-1;\r\n      size_t ymid = ((m_height-1)\/2);\r\n\r\n      for(size_t x=0;x&lt;(m_width\/2);x++) {\r\n        swap_pixel(x,ymid,(m_width-x-1),ymid);\r\n      }\r\n\r\n    } else h = (m_height\/2)-1;\r\n    for(size_t x=0;x&lt;m_width;x++) {\r\n      for(size_t y=0;y&lt;=h;y++) {\r\n        swap_pixel(x,y,m_width-x-1,m_height-y-1);\r\n      }\r\n    }\r\n  }\r\n<\/pre>\n<p>You need to provide image get and set, and swap_pixel. Complete example below:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\n#include &quot;tiffio.h&quot;\r\n#include &lt;iostream&gt;\r\n#include &lt;math.h&gt;\r\n#include &lt;vector&gt;\r\n#include &lt;map&gt;\r\n#include &lt;sys\/stat.h&gt;\r\n#include &lt;sys\/types.h&gt;\r\n#include &lt;sstream&gt;\r\n#include &lt;stdexcept&gt;\r\n\r\n#define TIFFSetR(pixel, x) ((unsigned char *)pixel)&#x5B;0] = x\r\n#define TIFFSetG(pixel, x) ((unsigned char *)pixel)&#x5B;1] = x\r\n#define TIFFSetB(pixel, x) ((unsigned char *)pixel)&#x5B;2] = x\r\n#define TIFFSetA(pixel, x) ((unsigned char *)pixel)&#x5B;3] = x\r\n\r\n\r\nclass BadConversion : public std::runtime_error {\r\npublic:\r\n BadConversion(const std::string&amp; s)\r\n      : std::runtime_error(s) {}\r\n};\r\n\r\ntemplate&lt;class _type&gt;\r\ninline std::string stringify(_type x)\r\n{\r\n  std::ostringstream o;\r\n  if (!(o &lt;&lt; std::fixed &lt;&lt; x))\r\n    throw BadConversion(&quot;stringify()&quot;);\r\n  return o.str();\r\n}\r\n\r\nusing namespace std;\r\n\r\nclass Image {\r\n\r\npublic:\r\n\r\n  Image() {\r\n  }\r\n\r\n  enum fragment_type { frag_type_arrow, frag_type_rectange } ;\r\n\r\n  void load_tiff(string input_filename) {\r\n\r\n    m_image_data.clear();\r\n\r\n    TIFF* tif = TIFFOpen(input_filename.c_str(), &quot;r&quot;);\r\n    if (tif) {\r\n      uint32 w, h;\r\n      size_t npixels;\r\n      uint32* raster;\r\n\r\n      TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &amp;w);\r\n      TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &amp;h);\r\n      npixels = w * h;\r\n      m_width = w;\r\n      m_height = h;\r\n\r\n      raster = (uint32*) _TIFFmalloc(npixels * sizeof (uint32));\r\n      if (raster != NULL) {\r\n\tif (TIFFReadRGBAImageOriented(tif, w, h, raster,ORIENTATION_TOPLEFT, 0)) {\r\n\t  for(size_t n=0;n&lt;npixels;n++) m_image_data.push_back(raster&#x5B;n]);\r\n\t}\r\n\t_TIFFfree(raster);\r\n      }\r\n      TIFFClose(tif);\r\n    }\r\n  }\r\n\r\n  void save_tiff_rgb(string output_filename) {\r\n    TIFF *output_image;\r\n\r\n    \/\/ Open the TIFF file\r\n    if((output_image = TIFFOpen(output_filename.c_str(), &quot;w&quot;)) == NULL){\r\n      cerr &lt;&lt; &quot;Unable to write tif file: &quot; &lt;&lt; output_filename &lt;&lt; endl;\r\n    }\r\n\r\n    \/\/ We need to set some values for basic tags before we can add any data\r\n    TIFFSetField(output_image, TIFFTAG_IMAGEWIDTH, m_width);\r\n    TIFFSetField(output_image, TIFFTAG_IMAGELENGTH, m_height);\r\n    TIFFSetField(output_image, TIFFTAG_BITSPERSAMPLE, 8);\r\n    TIFFSetField(output_image, TIFFTAG_SAMPLESPERPIXEL, 4);\r\n    TIFFSetField(output_image, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);\r\n\r\n    TIFFSetField(output_image, TIFFTAG_COMPRESSION, COMPRESSION_DEFLATE);\r\n    TIFFSetField(output_image, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);\r\n\r\n    \/\/ Write the information to the file\r\n    TIFFWriteEncodedStrip(output_image, 0, &amp;m_image_data&#x5B;0], m_width*m_height * 4);\r\n\r\n    \/\/ Close the file\r\n    TIFFClose(output_image);\r\n  }\r\n\r\n  bool is_on_image(size_t x,size_t y) {\r\n    if((x &lt; m_width) &amp;&amp; (y &lt; m_height)) return true;\r\n    return false;\r\n  }\r\n\r\n  uint32_t get(size_t x,size_t y) {\r\n    return m_image_data&#x5B;(y*m_width)+x];\r\n  }\r\n\r\n  void set(size_t x,size_t y,uint32_t value) {\r\n    m_image_data&#x5B;(y*m_width)+x] = value;\r\n  }\r\n\r\n  void swap_pixel(size_t x1,size_t y1,\r\n                  size_t x2,size_t y2) {\r\n\r\n    uint32_t t = get(x1,y1);\r\n    set(x1,y1,get(x2,y2));\r\n    set(x2,y2,t);\r\n  }\r\n\r\n  \/\/ Inplace 180 degree rotation.\r\n  void rotate180() {\r\n\r\n    size_t h;\r\n    if((m_height%2) == 1) {\r\n      h = (m_height\/2)-1;\r\n      size_t ymid = ((m_height-1)\/2);\r\n\r\n      for(size_t x=0;x&lt;(m_width\/2);x++) {\r\n        swap_pixel(x,ymid,(m_width-x-1),ymid);\r\n      }\r\n\r\n    } else h = (m_height\/2)-1;\r\n    for(size_t x=0;x&lt;m_width;x++) {\r\n      for(size_t y=0;y&lt;=h;y++) {\r\n        swap_pixel(x,y,m_width-x-1,m_height-y-1);\r\n      }\r\n    }\r\n  }\r\n\r\n  vector&lt;uint32_t&gt; m_image_data;\r\n  size_t m_width;\r\n  size_t m_height;\r\n};\r\n\r\nint main(int argc, char* argv&#x5B;]) {\r\n\r\n  Image i;\r\n  i.load_tiff(argv&#x5B;1]);\r\n  i.rotate180();\r\n  i.save_tiff_rgb(string(argv&#x5B;2]));\r\n}\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>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&lt;(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&lt;m_width;x++) { for(size_t y=0;y&lt;=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. [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[1],"tags":[15],"class_list":["post-557","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-libtiff"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p1RRoU-8Z","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/posts\/557","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/comments?post=557"}],"version-history":[{"count":2,"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/posts\/557\/revisions"}],"predecessor-version":[{"id":559,"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/posts\/557\/revisions\/559"}],"wp:attachment":[{"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/media?parent=557"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/categories?post=557"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/tags?post=557"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}