RAWK
Gigapixel Raw Image Processing Toolkit
 All Classes Functions Variables Pages
raw.hpp
1 // RAWK Copyright (C) 2014 Robert Kooima
2 //
3 // This program is free software: you can redistribute it and/or modify it
4 // under the terms of the GNU General Public License as published by the Free
5 // Software Foundation, either version 3 of the License, or (at your option)
6 // any later version.
7 //
8 // This program is distributed in the hope that it will be useful, but WITH-
9 // OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 // more details.
12 
13 #ifndef RAW_HPP
14 #define RAW_HPP
15 
16 #include <stdio.h>
17 #include <fcntl.h>
18 #include <stdint.h>
19 #include <unistd.h>
20 #include <string.h>
21 #include <sys/mman.h>
22 
23 #include <stdexcept>
24 #include <string>
25 
26 extern int errno;
27 
39 
40 //------------------------------------------------------------------------------
41 
43 
44 typedef int8_t * int8_p;
45 typedef uint8_t *uint8_p;
46 typedef int16_t * int16_p;
47 typedef uint16_t *uint16_p;
48 typedef int32_t * int32_p;
49 typedef uint32_t *uint32_p;
50 typedef float * float_p;
51 typedef double *double_p;
52 
53 //------------------------------------------------------------------------------
54 
56 
57 class raw_error : public std::runtime_error
58 {
59 public :
60  raw_error(const std::string& a,
61  const std::string& b) : std::runtime_error(a + ": " + b) { }
62 };
63 
64 //------------------------------------------------------------------------------
65 
67 
68 class raw
69 {
70 public:
71  raw(std::string name, size_t start, size_t height, size_t width, size_t depth, size_t size, bool write) :
72  name(name),
73  start(start),
74  height(height),
75  width(width),
76  depth(depth),
77  size(size),
78  file(0),
79  buffer(0),
80  pixels(0)
81  {
82  size_t length = start + height * width * depth * size;
83 
84  int mode = write ? O_RDWR | O_TRUNC | O_CREAT : O_RDONLY;
85  int prot = write ? PROT_READ | PROT_WRITE : PROT_READ;
86 
87  if ((file = open(name.c_str(), mode, 0666)) == -1)
88  throw raw_error(name, strerror(errno));
89 
90  if (write && ftruncate(file, length) == -1)
91  throw raw_error(name, strerror(errno));
92 
93  if ((buffer = mmap(0, length, prot, MAP_SHARED, file, 0)) == MAP_FAILED)
94  throw raw_error(name, strerror(errno));
95 
96  pixels = uint8_p(buffer) + start;
97  }
98 
99  virtual void put(int, int, int, double) = 0;
100  virtual double get(int, int, int) const = 0;
101 
102  std::string get_name() const { return name; }
103  int get_height() const { return height; }
104  int get_width() const { return width; }
105  int get_depth() const { return depth; }
106 
107  virtual ~raw()
108  {
109  size_t length = start + height * width * depth * size;
110 
111  if (munmap(buffer, length) == -1)
112  throw raw_error(name, strerror(errno));
113 
114  if (close(file) == -1)
115  throw raw_error(name, strerror(errno));
116  }
117 
118 protected:
119 
120  const void *data(int i, int j, int k) const
121  {
122  return (const uint8_t *) pixels + (((i * width) + j) * depth + k) * size;
123  }
124  void *data(int i, int j, int k)
125  {
126  return (uint8_t *) pixels + (((i * width) + j) * depth + k) * size;
127  }
128 
129  std::string name;
130 
131  size_t start;
132  size_t height;
133  size_t width;
134  size_t depth;
135  size_t size;
136  int file;
137  void *buffer;
138  void *pixels;
139 };
140 
141 //------------------------------------------------------------------------------
142 
143 // Clamps prevent under and overflow when casting to normalized sample types.
144 
145 static inline double uclamp(double d)
146 {
147  if (d > 1.0) return 1;
148  else if (d < 0.0) return 0;
149  else return d;
150 }
151 
152 static inline double clamp(double d)
153 {
154  if (d > 1.0) return 1;
155  else if (d < -1.0) return -1;
156  else return d;
157 }
158 
159 //------------------------------------------------------------------------------
160 
161 // Byte swappers for all sample types.
162 
163 static inline void swap(uint8_t *a, uint8_t *b)
164 {
165  uint8_t tt;
166  tt = *a;
167  *a = *b;
168  *b = tt;
169 }
170 
171 static inline int16_t swap(int16_t n)
172 {
173  swap(uint8_p(&n) + 0, uint8_p(&n) + 1);
174  return n;
175 }
176 
177 static inline uint16_t swap(uint16_t n)
178 {
179  swap(uint8_p(&n) + 0, uint8_p(&n) + 1);
180  return n;
181 }
182 
183 static inline int32_t swap(int32_t n)
184 {
185  swap(uint8_p(&n) + 0, uint8_p(&n) + 3);
186  swap(uint8_p(&n) + 1, uint8_p(&n) + 2);
187  return n;
188 }
189 
190 static inline uint32_t swap(uint32_t n)
191 {
192  swap(uint8_p(&n) + 0, uint8_p(&n) + 3);
193  swap(uint8_p(&n) + 1, uint8_p(&n) + 2);
194  return n;
195 }
196 
197 static inline float swap(float n)
198 {
199  swap(uint8_p(&n) + 0, uint8_p(&n) + 3);
200  swap(uint8_p(&n) + 1, uint8_p(&n) + 2);
201  return n;
202 }
203 
204 static inline double swap(double n)
205 {
206  swap(uint8_p(&n) + 0, uint8_p(&n) + 7);
207  swap(uint8_p(&n) + 1, uint8_p(&n) + 6);
208  swap(uint8_p(&n) + 2, uint8_p(&n) + 5);
209  swap(uint8_p(&n) + 3, uint8_p(&n) + 4);
210  return n;
211 }
212 
213 //------------------------------------------------------------------------------
214 
216 
217 class rawc : public raw
218 {
219 public:
220  rawc(std::string a, size_t o, size_t h, size_t w, size_t d, bool m)
221  : raw(a, o, h, w, d, sizeof (int8_t), m) { }
222 
223  void put(int i, int j, int k, double d)
224  {
225  *int8_p(data(i, j, k)) = int8_t(clamp(d) * INT8_MAX);
226  }
227  double get(int i, int j, int k) const
228  {
229  return double(*int8_p(data(i, j, k))) / INT8_MAX;
230  }
231 };
232 
234 
235 class rawb : public raw
236 {
237 public:
238  rawb(std::string a, size_t o, size_t h, size_t w, size_t d, bool m)
239  : raw(a, o, h, w, d, sizeof (uint8_t), m) { }
240 
241  void put(int i, int j, int k, double d)
242  {
243  *uint8_p(data(i, j, k)) = uint8_t(uclamp(d) * UINT8_MAX);
244  }
245  double get(int i, int j, int k) const
246  {
247  return double(*uint8_p(data(i, j, k))) / UINT8_MAX;
248  }
249 };
250 
251 //------------------------------------------------------------------------------
252 
254 
255 class raws : public raw
256 {
257 public:
258  raws(std::string a, size_t o, size_t h, size_t w, size_t d, bool m)
259  : raw(a, o, h, w, d, sizeof (int16_t), m) { }
260 
261  void put(int i, int j, int k, double d)
262  {
263  *int16_p(data(i, j, k)) = int16_t(clamp(d) * INT16_MAX);
264  }
265  double get(int i, int j, int k) const
266  {
267  return double(*int16_p(data(i, j, k))) / INT16_MAX;
268  }
269 };
270 
272 
273 class rawS : public raw
274 {
275 public:
276  rawS(std::string a, size_t o, size_t h, size_t w, size_t d, bool m)
277  : raw(a, o, h, w, d, sizeof (int16_t), m) { }
278 
279  void put(int i, int j, int k, double d)
280  {
281  *int16_p(data(i, j, k)) = swap(int16_t(clamp(d) * INT16_MAX));
282  }
283  double get(int i, int j, int k) const
284  {
285  return double(swap(*int16_p(data(i, j, k)))) / INT16_MAX;
286  }
287 };
288 
289 //------------------------------------------------------------------------------
290 
292 
293 class rawu : public raw
294 {
295 public:
296  rawu(std::string a, size_t o, size_t h, size_t w, size_t d, bool m)
297  : raw(a, o, h, w, d, sizeof (uint16_t), m) { }
298 
299  void put(int i, int j, int k, double d)
300  {
301  *uint16_p(data(i, j, k)) = uint16_t(uclamp(d) * UINT16_MAX);
302  }
303  double get(int i, int j, int k) const
304  {
305  return double(*uint16_p(data(i, j, k))) / UINT16_MAX;
306  }
307 };
308 
310 
311 class rawU : public raw
312 {
313 public:
314  rawU(std::string a, size_t o, size_t h, size_t w, size_t d, bool m)
315  : raw(a, o, h, w, d, sizeof (uint16_t), m) { }
316 
317  void put(int i, int j, int k, double d)
318  {
319  *uint16_p(data(i, j, k)) = swap(uint16_t(uclamp(d) * UINT16_MAX));
320  }
321  double get(int i, int j, int k) const
322  {
323  return double(swap(*uint16_p(data(i, j, k)))) / UINT16_MAX;
324  }
325 };
326 
327 //------------------------------------------------------------------------------
328 
330 
331 class rawi : public raw
332 {
333 public:
334  rawi(std::string a, size_t o, size_t h, size_t w, size_t d, bool m)
335  : raw(a, o, h, w, d, sizeof (int32_t), m) { }
336 
337  void put(int i, int j, int k, double d)
338  {
339  *int32_p(data(i, j, k)) = int32_t(clamp(d) * INT32_MAX);
340  }
341  double get(int i, int j, int k) const
342  {
343  return double(*int32_p(data(i, j, k))) / INT32_MAX;
344  }
345 };
346 
348 
349 class rawI : public raw
350 {
351 public:
352  rawI(std::string a, size_t o, size_t h, size_t w, size_t d, bool m)
353  : raw(a, o, h, w, d, sizeof (int32_t), m) { }
354 
355  void put(int i, int j, int k, double d)
356  {
357  *int32_p(data(i, j, k)) = swap(int32_t(clamp(d) * INT32_MAX));
358  }
359  double get(int i, int j, int k) const
360  {
361  return double(swap(*int32_p(data(i, j, k)))) / INT32_MAX;
362  }
363 };
364 
365 //------------------------------------------------------------------------------
366 
368 
369 class rawl : public raw
370 {
371 public:
372  rawl(std::string a, size_t o, size_t h, size_t w, size_t d, bool m)
373  : raw(a, o, h, w, d, sizeof (uint32_t), m) { }
374 
375  void put(int i, int j, int k, double d)
376  {
377  *uint32_p(data(i, j, k)) = uint32_t(uclamp(d) * UINT32_MAX);
378  }
379  double get(int i, int j, int k) const
380  {
381  return double(*uint32_p(data(i, j, k))) / UINT32_MAX;
382  }
383 };
384 
386 
387 class rawL : public raw
388 {
389 public:
390  rawL(std::string a, size_t o, size_t h, size_t w, size_t d, bool m)
391  : raw(a, o, h, w, d, sizeof (uint32_t), m) { }
392 
393  void put(int i, int j, int k, double d)
394  {
395  *uint32_p(data(i, j, k)) = swap(uint32_t(uclamp(d) * UINT32_MAX));
396  }
397  double get(int i, int j, int k) const
398  {
399  return double(swap(*uint32_p(data(i, j, k)))) / UINT32_MAX;
400  }
401 };
402 
403 //------------------------------------------------------------------------------
404 
406 
407 class rawf : public raw
408 {
409 public:
410  rawf(std::string a, size_t o, size_t h, size_t w, size_t d, bool m)
411  : raw(a, o, h, w, d, sizeof (float), m) { }
412 
413  void put(int i, int j, int k, double d)
414  {
415  *float_p(data(i, j, k)) = float(d);
416  }
417  double get(int i, int j, int k) const
418  {
419  return double(*float_p(data(i, j, k)));
420  }
421 };
422 
424 
425 class rawF : public raw
426 {
427 public:
428  rawF(std::string a, size_t o, size_t h, size_t w, size_t d, bool m)
429  : raw(a, o, h, w, d, sizeof (float), m) { }
430 
431  void put(int i, int j, int k, double d)
432  {
433  *float_p(data(i, j, k)) = swap(float(d));
434  }
435  double get(int i, int j, int k) const
436  {
437  return double(swap(*float_p(data(i, j, k))));
438  }
439 };
440 
441 //------------------------------------------------------------------------------
442 
444 
445 class rawd : public raw
446 {
447 public:
448  rawd(std::string a, size_t o, size_t h, size_t w, size_t d, bool m)
449  : raw(a, o, h, w, d, sizeof (double), m) { }
450 
451  void put(int i, int j, int k, double d)
452  {
453  *double_p(data(i, j, k)) = d;
454  }
455  double get(int i, int j, int k) const
456  {
457  return *double_p(data(i, j, k));
458  }
459 };
460 
462 
463 class rawD : public raw
464 {
465 public:
466  rawD(std::string a, size_t o, size_t h, size_t w, size_t d, bool m)
467  : raw(a, o, h, w, d, sizeof (double), m) { }
468 
469  void put(int i, int j, int k, double d)
470  {
471  *double_p(data(i, j, k)) = swap(d);
472  }
473  double get(int i, int j, int k) const
474  {
475  return swap(*double_p(data(i, j, k)));
476  }
477 };
478 
479 //------------------------------------------------------------------------------
480 
481 #endif
RAW image file.
Definition: raw.hpp:68
RAW image file I/O error.
Definition: raw.hpp:57
Signed 32-bit RAW adapter.
Definition: raw.hpp:331
Byte-swapped single precision floating point RAW adapter.
Definition: raw.hpp:463
Single precision floating point RAW adapter.
Definition: raw.hpp:445
Unigned 32-bit RAW adapter.
Definition: raw.hpp:369
Unsigned 16-bit RAW adapter.
Definition: raw.hpp:293
Byte-swapped unsigned 16-bit RAW adapter.
Definition: raw.hpp:311
Unsigned 8-bit RAW adapter.
Definition: raw.hpp:235
Signed 8-bit RAW adapter.
Definition: raw.hpp:217
Byte-swapped single precision floating point RAW adapter.
Definition: raw.hpp:425
Single precision floating point RAW adapter.
Definition: raw.hpp:407
Signed 16-bit RAW adapter.
Definition: raw.hpp:255
Byte-swapped signed 16-bit RAW adapter.
Definition: raw.hpp:273
Byte-swapped signed 32-bit RAW adapter.
Definition: raw.hpp:349
Byte-swapped unsigned 32-bit RAW adapter.
Definition: raw.hpp:387