SOPT
Sparse OPTimisation
utilities.cc
Go to the documentation of this file.
1 #include "sopt/utilities.h"
2 #include "sopt/config.h"
3 #include <fstream>
4 #include <tiff.h>
5 #include <tiffio.h>
6 #include "sopt/exception.h"
7 #include "sopt/logging.h"
8 #include <vector>
9 #include "sopt/types.h"
10 
11 namespace {
14 double convert_to_greyscale(uint32_t &pixel) {
15  uint8_t const blue = TIFFGetB(pixel);
16  uint8_t const green = TIFFGetG(pixel);
17  uint8_t const red = TIFFGetR(pixel);
18  return static_cast<double>(blue + green + red) / (3e0 * 255e0);
19 }
21 uint32_t convert_from_greyscale(double pixel) {
22  uint32_t result = 0;
23  uint8_t *ptr = reinterpret_cast<uint8_t *>(&result);
24  auto const g = [](double p) -> uint8_t {
25  auto const scaled = 255e0 * p;
26  if (scaled < 0) return 0;
27  return scaled > 255 ? 255 : static_cast<uint8_t>(scaled);
28  };
29  ptr[0] = g(pixel);
30  ptr[1] = g(pixel);
31  ptr[2] = g(pixel);
32  ptr[3] = 255;
33  return result;
34 }
35 } // namespace
36 
37 namespace sopt::utilities {
38 Image<> read_tiff(std::string const &filename) {
39  SOPT_MEDIUM_LOG("Reading image file {} ", filename);
40  TIFF *tif = TIFFOpen(filename.c_str(), "r");
41  if (tif == nullptr) SOPT_THROW("Could not open file ") << filename;
42 
43  uint32_t width;
44  uint32_t height;
45  uint32_t t;
46 
47  TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
48  TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
49  TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &t);
50  SOPT_LOW_LOG("- image size {}, {} ", width, height);
51  Image<> result = Image<>::Zero(height, width);
52 
53  uint32_t *raster = static_cast<uint32_t *>(_TIFFmalloc(width * height * sizeof(uint32_t)));
54  if (raster == nullptr) SOPT_THROW("Could not allocate memory to read file ") << filename;
55  if (TIFFReadRGBAImage(tif, width, height, raster, 0) == 0)
56  SOPT_THROW("Could not read file ") << filename;
57 
58  uint32_t *pixel = raster;
59  for (uint32_t i(0); i < height; ++i)
60  for (uint32_t j(0); j < width; ++j, ++pixel) result(i, j) = convert_to_greyscale(*pixel);
61 
62  _TIFFfree(raster);
63 
64  TIFFClose(tif);
65  return result;
66 }
67 
68 void write_tiff(Image<> const &image, std::string const &filename) {
69  SOPT_MEDIUM_LOG("Writing image file {} ", filename);
70  SOPT_LOW_LOG("- image size {}, {} ", image.rows(), image.cols());
71  TIFF *tif = TIFFOpen(filename.c_str(), "w");
72  if (tif == nullptr) SOPT_THROW("Could not open file ") << filename;
73 
74  uint32_t const width = image.cols();
75  uint32_t const height = image.rows();
76 
77  SOPT_TRACE("Allocating buffer");
78  std::vector<uint32_t> raster(width * height);
79 
80  TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width);
81  TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height);
82  TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, sizeof(decltype(raster)::value_type));
83  TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
84  TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, height);
85  TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
86  TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_LZW);
87  TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
88  TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_BOTLEFT);
89 
90  SOPT_TRACE("Initializing buffer");
91  auto pixel = raster.begin();
92  for (uint32_t i(0); i < height; ++i)
93  for (uint32_t j(0); j < width; ++j, ++pixel) *pixel = convert_from_greyscale(image(i, j));
94 
95  SOPT_TRACE("Writing strip");
96  TIFFWriteEncodedStrip(tif, 0, raster.data(), width * height * sizeof(decltype(raster)::value_type));
97 
98  TIFFWriteDirectory(tif);
99  SOPT_TRACE("Closing tif");
100  TIFFClose(tif);
101  SOPT_TRACE("Freeing raster");
102 }
103 } // namespace sopt::utilities
#define SOPT_THROW(MSG)
Definition: exception.h:46
#define SOPT_LOW_LOG(...)
Low priority message.
Definition: logging.h:227
#define SOPT_TRACE(...)
Definition: logging.h:220
#define SOPT_MEDIUM_LOG(...)
Medium priority message.
Definition: logging.h:225
void write_tiff(Image<> const &image, std::string const &filename)
Writes a tiff greyscale file.
Definition: utilities.cc:68
Image read_tiff(std::string const &filename)
Reads tiff image.
Definition: utilities.cc:38
Eigen::Array< T, Eigen::Dynamic, Eigen::Dynamic > Image
A 2-dimensional list of elements of given type.
Definition: types.h:39