OpenImageIO
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
imageio.h
Go to the documentation of this file.
1 /*
2  Copyright 2008 Larry Gritz and the other authors and contributors.
3  All Rights Reserved.
4  Based on BSD-licensed software Copyright 2004 NVIDIA Corp.
5 
6  Redistribution and use in source and binary forms, with or without
7  modification, are permitted provided that the following conditions are
8  met:
9  * Redistributions of source code must retain the above copyright
10  notice, this list of conditions and the following disclaimer.
11  * Redistributions in binary form must reproduce the above copyright
12  notice, this list of conditions and the following disclaimer in the
13  documentation and/or other materials provided with the distribution.
14  * Neither the name of the software's owners nor the names of its
15  contributors may be used to endorse or promote products derived from
16  this software without specific prior written permission.
17  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 
29  (This is the Modified BSD License)
30 */
31 
32 
41 
42 
43 #ifndef OPENIMAGEIO_IMAGEIO_H
44 #define OPENIMAGEIO_IMAGEIO_H
45 
46 #if defined(_MSC_VER)
47 // Ignore warnings about DLL exported classes with member variables that are template classes.
48 // This happens with the std::vector<T> and std::string members of the classes below.
49 # pragma warning (disable : 4251)
50 #endif
51 
52 #include <vector>
53 #include <string>
54 #include <limits>
55 #include <cmath>
56 
57 #include "export.h"
58 #include "typedesc.h" /* Needed for TypeDesc definition */
59 #include "paramlist.h"
60 #include "version.h"
61 
62 OIIO_NAMESPACE_ENTER
63 {
64 
69 typedef ptrdiff_t stride_t;
70 
71 
75 #if defined(LINUX64) || defined(_WIN64) /* add others if we know for sure size_t is ok */
76 typedef size_t imagesize_t;
77 #else
78 typedef unsigned long long imagesize_t;
79 #endif
80 
81 
82 
85 const stride_t AutoStride = std::numeric_limits<stride_t>::min();
86 
87 
88 
94 typedef bool (*ProgressCallback)(void *opaque_data, float portion_done);
95 
96 
97 
98 typedef ParamValue ImageIOParameter;
100 
101 
102 
105 class OIIO_API ImageSpec {
106 public:
107  int x, y, z;
108  int width;
109  int height;
110  int depth;
111  int full_x;
112  int full_y;
113  int full_z;
119  int tile_depth;
120 
121  int nchannels;
122  TypeDesc format;
123  std::vector<TypeDesc> channelformats;
124  std::vector<std::string> channelnames;
125 
127  int z_channel;
128  bool deep;
129 
130  // quantize is used for ImageOutput
133  int quant_min;
134  int quant_max;
135 
145  ImageIOParameterList extra_attribs;
146 
149  ImageSpec (TypeDesc format = TypeDesc::UNKNOWN);
150 
153  ImageSpec (int xres, int yres, int nchans, TypeDesc fmt = TypeDesc::UINT8);
154 
157  void set_format (TypeDesc fmt);
158 
161  void default_channel_names ();
162 
165  static TypeDesc format_from_quantize (int quant_black, int quant_white,
166  int quant_min, int quant_max);
167 
170  size_t channel_bytes() const { return format.size(); }
171 
177  size_t channel_bytes (int chan, bool native=false) const;
178 
186  size_t pixel_bytes (bool native=false) const;
187 
196  size_t pixel_bytes (int chbegin, int chend, bool native=false) const;
197 
205  imagesize_t scanline_bytes (bool native=false) const;
206 
210  imagesize_t tile_pixels () const;
211 
219  imagesize_t tile_bytes (bool native=false) const;
220 
224  imagesize_t image_pixels () const;
225 
233  imagesize_t image_bytes (bool native=false) const;
234 
240  bool size_t_safe() const {
241  const imagesize_t big = std::numeric_limits<size_t>::max();
242  return image_bytes() < big && scanline_bytes() < big &&
243  tile_bytes() < big;
244  }
245 
249  static void auto_stride (stride_t &xstride, stride_t &ystride,
250  stride_t &zstride, stride_t channelsize,
251  int nchannels, int width, int height) {
252  if (xstride == AutoStride)
253  xstride = nchannels * channelsize;
254  if (ystride == AutoStride)
255  ystride = xstride * width;
256  if (zstride == AutoStride)
257  zstride = ystride * height;
258  }
259 
263  static void auto_stride (stride_t &xstride, stride_t &ystride,
264  stride_t &zstride, TypeDesc format,
265  int nchannels, int width, int height) {
266  auto_stride (xstride, ystride, zstride, format.size(),
267  nchannels, width, height);
268  }
269 
272  static void auto_stride (stride_t &xstride, TypeDesc format, int nchannels) {
273  if (xstride == AutoStride)
274  xstride = nchannels * format.size();
275  }
276 
279  void attribute (const std::string &name, TypeDesc type, const void *value);
280 
283  void attribute (const std::string &name, TypeDesc type, const std::string &value);
284 
287  void attribute (const std::string &name, unsigned int value) {
288  attribute (name, TypeDesc::UINT, &value);
289  }
290 
293  void attribute (const std::string &name, int value) {
294  attribute (name, TypeDesc::INT, &value);
295  }
296 
299  void attribute (const std::string &name, float value) {
300  attribute (name, TypeDesc::FLOAT, &value);
301  }
302 
305  void attribute (const std::string &name, const char *value) {
306  attribute (name, TypeDesc::STRING, &value);
307  }
308 
311  void attribute (const std::string &name, const std::string &value) {
312  attribute (name, value.c_str());
313  }
314 
317  void erase_attribute (const std::string &name,
318  TypeDesc searchtype=TypeDesc::UNKNOWN,
319  bool casesensitive=false);
320 
323  ImageIOParameter * find_attribute (const std::string &name,
324  TypeDesc searchtype=TypeDesc::UNKNOWN,
325  bool casesensitive=false);
326  const ImageIOParameter *find_attribute (const std::string &name,
327  TypeDesc searchtype=TypeDesc::UNKNOWN,
328  bool casesensitive=false) const;
329 
333  int get_int_attribute (const std::string &name, int defaultval=0) const;
334 
338  float get_float_attribute (const std::string &name,
339  float defaultval=0) const;
340 
343  std::string get_string_attribute (const std::string &name,
344  const std::string &defaultval = std::string()) const;
345 
350  std::string metadata_val (const ImageIOParameter &p,
351  bool human=false) const;
352 
355  std::string to_xml () const;
356 
359  void from_xml (const char *xml);
360 
364  bool valid_tile_range (int xbegin, int xend, int ybegin, int yend,
365  int zbegin, int zend) {
366  return (tile_width &&
367  ((xbegin-x) % tile_width) == 0 &&
368  ((ybegin-y) % tile_height) == 0 &&
369  ((zbegin-z) % tile_depth) == 0 &&
370  (((xend-x) % tile_width) == 0 || (xend-x) == width) &&
371  (((yend-y) % tile_height) == 0 || (yend-y) == height) &&
372  (((zend-z) % tile_depth) == 0 || (zend-z) == depth));
373  }
374 
376  TypeDesc channelformat (int chan) const {
377  return chan >= (int)channelformats.size() ? format : channelformats[chan];
378  }
379 
384  void get_channelformats (std::vector<TypeDesc> &formats) const {
385  formats = channelformats;
386  if ((int)formats.size() < nchannels)
387  formats.resize (nchannels, format);
388  }
389 };
390 
391 
392 
394 struct OIIO_API DeepData {
395 public:
396  int npixels, nchannels;
397  std::vector<TypeDesc> channeltypes; // for each channel [c]
398  std::vector<unsigned int> nsamples;// for each pixel [z][y][x]
399  std::vector<void *> pointers; // for each channel per pixel [z][y][x][c]
400  std::vector<char> data; // for each sample [z][y][x][c][s]
401 
402  DeepData () : npixels(0), nchannels(0) { }
404  void init (int npix, int nchan,
405  const TypeDesc *chbegin, const TypeDesc *chend);
408  void alloc ();
410  void clear ();
412  void free ();
413 };
414 
415 
416 
419 class OIIO_API ImageInput {
420 public:
436  static ImageInput *open (const std::string &filename,
437  const ImageSpec *config = NULL);
438 
449  static ImageInput *create (const std::string &filename,
450  const std::string &plugin_searchpath="");
451 
452  ImageInput () { }
453  virtual ~ImageInput () { }
454 
457  virtual const char *format_name (void) const = 0;
458 
466  virtual bool valid_file (const std::string &filename) const;
467 
473  virtual bool open (const std::string &name, ImageSpec &newspec) = 0;
474 
480  virtual bool open (const std::string &name, ImageSpec &newspec,
481  const ImageSpec & /*config*/) { return open(name,newspec); }
482 
487  const ImageSpec &spec (void) const { return m_spec; }
488 
500  virtual bool supports (const std::string & /*feature*/) const { return false; }
501 
504  virtual bool close () = 0;
505 
509  virtual int current_subimage (void) const { return 0; }
510 
514  virtual int current_miplevel (void) const { return 0; }
515 
527  virtual bool seek_subimage (int subimage, int miplevel,
528  ImageSpec &newspec) {
529  if (subimage == current_subimage() && miplevel == current_miplevel()) {
530  newspec = spec();
531  return true;
532  }
533  return false;
534  }
535 
538  bool seek_subimage (int subimage, ImageSpec &newspec) {
539  return seek_subimage (subimage, 0 /* miplevel */, newspec);
540  }
541 
558  virtual bool read_scanline (int y, int z, TypeDesc format, void *data,
559  stride_t xstride=AutoStride);
560 
563  bool read_scanline (int y, int z, float *data) {
564  return read_scanline (y, z, TypeDesc::FLOAT, data);
565  }
566 
575  virtual bool read_scanlines (int ybegin, int yend, int z,
576  TypeDesc format, void *data,
577  stride_t xstride=AutoStride,
578  stride_t ystride=AutoStride);
579 
588  virtual bool read_scanlines (int ybegin, int yend, int z,
589  int chbegin, int chend,
590  TypeDesc format, void *data,
591  stride_t xstride=AutoStride,
592  stride_t ystride=AutoStride);
593 
613  virtual bool read_tile (int x, int y, int z, TypeDesc format,
614  void *data, stride_t xstride=AutoStride,
615  stride_t ystride=AutoStride,
616  stride_t zstride=AutoStride);
617 
620  bool read_tile (int x, int y, int z, float *data) {
621  return read_tile (x, y, z, TypeDesc::FLOAT, data,
622  AutoStride, AutoStride, AutoStride);
623  }
624 
637  virtual bool read_tiles (int xbegin, int xend, int ybegin, int yend,
638  int zbegin, int zend, TypeDesc format,
639  void *data, stride_t xstride=AutoStride,
640  stride_t ystride=AutoStride,
641  stride_t zstride=AutoStride);
642 
651  virtual bool read_tiles (int xbegin, int xend, int ybegin, int yend,
652  int zbegin, int zend,
653  int chbegin, int chend, TypeDesc format,
654  void *data, stride_t xstride=AutoStride,
655  stride_t ystride=AutoStride,
656  stride_t zstride=AutoStride);
657 
673  virtual bool read_image (TypeDesc format, void *data,
674  stride_t xstride=AutoStride,
675  stride_t ystride=AutoStride,
676  stride_t zstride=AutoStride,
677  ProgressCallback progress_callback=NULL,
678  void *progress_callback_data=NULL);
679 
682  bool read_image (float *data) {
683  return read_image (TypeDesc::FLOAT, data);
684  }
685 
686 
692  virtual bool read_native_scanline (int y, int z, void *data) = 0;
693 
701  virtual bool read_native_scanlines (int ybegin, int yend, int z,
702  void *data);
703 
709  virtual bool read_native_scanlines (int ybegin, int yend, int z,
710  int chbegin, int chend, void *data);
711 
718  virtual bool read_native_tile (int x, int y, int z, void *data);
719 
727  virtual bool read_native_tiles (int xbegin, int xend, int ybegin, int yend,
728  int zbegin, int zend, void *data);
729 
735  virtual bool read_native_tiles (int xbegin, int xend, int ybegin, int yend,
736  int zbegin, int zend,
737  int chbegin, int chend, void *data);
738 
743  virtual bool read_native_deep_scanlines (int ybegin, int yend, int z,
744  int chbegin, int chend,
745  DeepData &deepdata);
746 
751  virtual bool read_native_deep_tiles (int xbegin, int xend,
752  int ybegin, int yend,
753  int zbegin, int zend,
754  int chbegin, int chend,
755  DeepData &deepdata);
756 
759  virtual bool read_native_deep_image (DeepData &deepdata);
760 
761 
764  virtual int send_to_input (const char *format, ...);
765  int send_to_client (const char *format, ...);
766 
771  std::string geterror () const {
772  std::string e = m_errmessage;
773  m_errmessage.clear ();
774  return e;
775  }
776 
777 protected:
780  // void error (const char *format, ...) const;
781  TINYFORMAT_WRAP_FORMAT (void, error, const,
782  std::ostringstream msg;, msg, append_error(msg.str());)
783 
784 protected:
785  ImageSpec m_spec; // format spec of the current open subimage/MIPlevel
786 
787 private:
788  mutable std::string m_errmessage; // private storage of error message
789  void append_error (const std::string& message) const; // add to m_errmessage
790  static ImageInput *create (const std::string &filename, bool do_open,
791  const std::string &plugin_searchpath);
792 
793 };
794 
795 
796 
797 
800 class OIIO_API ImageOutput {
801 public:
807  static ImageOutput *create (const std::string &filename,
808  const std::string &plugin_searchpath="");
809 
810  ImageOutput () { }
811  virtual ~ImageOutput () { }
812 
815  virtual const char *format_name (void) const = 0;
816 
817  // Overrride these functions in your derived output class
818  // to inform the client which formats are supported
819 
861  virtual bool supports (const std::string & /*feature*/) const { return false; }
862 
863  enum OpenMode { Create, AppendSubimage, AppendMIPLevel };
864 
873  virtual bool open (const std::string &name, const ImageSpec &newspec,
874  OpenMode mode=Create) = 0;
875 
891  virtual bool open (const std::string &name, int subimages,
892  const ImageSpec *specs) {
893  // Default implementation: just a regular open, assume that
894  // appending will work.
895  return open (name, specs[0]);
896  }
897 
901  const ImageSpec &spec (void) const { return m_spec; }
902 
906  virtual bool close () = 0;
907 
921  virtual bool write_scanline (int y, int z, TypeDesc format,
922  const void *data, stride_t xstride=AutoStride);
923 
929  virtual bool write_scanlines (int ybegin, int yend, int z,
930  TypeDesc format, const void *data,
931  stride_t xstride=AutoStride,
932  stride_t ystride=AutoStride);
933 
950  virtual bool write_tile (int x, int y, int z, TypeDesc format,
951  const void *data, stride_t xstride=AutoStride,
952  stride_t ystride=AutoStride,
953  stride_t zstride=AutoStride);
954 
963  virtual bool write_tiles (int xbegin, int xend, int ybegin, int yend,
964  int zbegin, int zend, TypeDesc format,
965  const void *data, stride_t xstride=AutoStride,
966  stride_t ystride=AutoStride,
967  stride_t zstride=AutoStride);
968 
987  virtual bool write_rectangle (int xbegin, int xend, int ybegin, int yend,
988  int zbegin, int zend, TypeDesc format,
989  const void *data, stride_t xstride=AutoStride,
990  stride_t ystride=AutoStride,
991  stride_t zstride=AutoStride);
992 
1008  virtual bool write_image (TypeDesc format, const void *data,
1009  stride_t xstride=AutoStride,
1010  stride_t ystride=AutoStride,
1011  stride_t zstride=AutoStride,
1012  ProgressCallback progress_callback=NULL,
1013  void *progress_callback_data=NULL);
1014 
1017  virtual bool write_deep_scanlines (int ybegin, int yend, int z,
1018  const DeepData &deepdata);
1019 
1025  virtual bool write_deep_tiles (int xbegin, int xend, int ybegin, int yend,
1026  int zbegin, int zend,
1027  const DeepData &deepdata);
1028 
1030  virtual bool write_deep_image (const DeepData &deepdata);
1031 
1050  virtual bool copy_image (ImageInput *in);
1051 
1054  virtual int send_to_output (const char *format, ...);
1055  int send_to_client (const char *format, ...);
1056 
1061  std::string geterror () const {
1062  std::string e = m_errmessage;
1063  m_errmessage.clear ();
1064  return e;
1065  }
1066 
1067 protected:
1071  TINYFORMAT_WRAP_FORMAT (void, error, const,
1072  std::ostringstream msg;, msg, append_error(msg.str());)
1073 
1082  const void *to_native_scanline (TypeDesc format,
1083  const void *data, stride_t xstride,
1084  std::vector<unsigned char> &scratch);
1085  const void *to_native_tile (TypeDesc format, const void *data,
1086  stride_t xstride, stride_t ystride,
1087  stride_t zstride,
1088  std::vector<unsigned char> &scratch);
1089  const void *to_native_rectangle (int xbegin, int xend, int ybegin, int yend,
1090  int zbegin, int zend,
1091  TypeDesc format, const void *data,
1092  stride_t xstride, stride_t ystride,
1093  stride_t zstride,
1094  std::vector<unsigned char> &scratch);
1095 
1096 protected:
1098 
1099 private:
1100  void append_error (const std::string& message) const; // add to m_errmessage
1101  mutable std::string m_errmessage;
1102 };
1103 
1104 
1105 
1106 // Utility functions
1107 
1111 OIIO_API int openimageio_version ();
1112 
1118 OIIO_API std::string geterror ();
1119 
1140 OIIO_API bool attribute (const std::string &name, TypeDesc type,
1141  const void *val);
1142 // Shortcuts for common types
1143 inline bool attribute (const std::string &name, int val) {
1144  return attribute (name, TypeDesc::TypeInt, &val);
1145 }
1146 inline bool attribute (const std::string &name, float val) {
1147  return attribute (name, TypeDesc::TypeFloat, &val);
1148 }
1149 inline bool attribute (const std::string &name, const char *val) {
1150  return attribute (name, TypeDesc::TypeString, &val);
1151 }
1152 inline bool attribute (const std::string &name, const std::string &val) {
1153  const char *s = val.c_str();
1154  return attribute (name, TypeDesc::TypeString, &s);
1155 }
1156 
1162 OIIO_API bool getattribute (const std::string &name, TypeDesc type,
1163  void *val);
1164 // Shortcuts for common types
1165 inline bool getattribute (const std::string &name, int &val) {
1166  return getattribute (name, TypeDesc::TypeInt, &val);
1167 }
1168 inline bool getattribute (const std::string &name, float &val) {
1169  return getattribute (name, TypeDesc::TypeFloat, &val);
1170 }
1171 inline bool getattribute (const std::string &name, char **val) {
1172  return getattribute (name, TypeDesc::TypeString, val);
1173 }
1174 inline bool getattribute (const std::string &name, std::string &val) {
1175  const char *s = NULL;
1176  bool ok = getattribute (name, TypeDesc::TypeString, &s);
1177  if (ok)
1178  val = s ? s : "";
1179  return ok;
1180 }
1181 
1182 
1185 OIIO_API int quantize (float value, int quant_black, int quant_white,
1186  int quant_min, int quant_max);
1187 
1193 OIIO_API bool convert_types (TypeDesc src_type, const void *src,
1194  TypeDesc dst_type, void *dst, int n);
1195 
1199 OIIO_API bool convert_types (TypeDesc src_type, const void *src,
1200  TypeDesc dst_type, void *dst, int n,
1201  int alpha_channel, int z_channel = -1);
1202 
1212 OIIO_API bool convert_image (int nchannels, int width, int height, int depth,
1213  const void *src, TypeDesc src_type,
1214  stride_t src_xstride, stride_t src_ystride,
1215  stride_t src_zstride,
1216  void *dst, TypeDesc dst_type,
1217  stride_t dst_xstride, stride_t dst_ystride,
1218  stride_t dst_zstride,
1219  int alpha_channel = -1, int z_channel = -1);
1220 
1223 OIIO_API bool parallel_convert_image (
1224  int nchannels, int width, int height, int depth,
1225  const void *src, TypeDesc src_type,
1226  stride_t src_xstride, stride_t src_ystride,
1227  stride_t src_zstride,
1228  void *dst, TypeDesc dst_type,
1229  stride_t dst_xstride, stride_t dst_ystride,
1230  stride_t dst_zstride,
1231  int alpha_channel=-1, int z_channel=-1, int nthreads=0);
1232 
1233 
1242 OIIO_API bool copy_image (int nchannels, int width, int height, int depth,
1243  const void *src, stride_t pixelsize,
1244  stride_t src_xstride, stride_t src_ystride,
1245  stride_t src_zstride,
1246  void *dst, stride_t dst_xstride,
1247  stride_t dst_ystride, stride_t dst_zstride);
1248 
1253 OIIO_API bool decode_exif (const void *exif, int length, ImageSpec &spec);
1254 
1257 OIIO_API void encode_exif (const ImageSpec &spec, std::vector<char> &blob);
1258 
1267 OIIO_API bool decode_iptc_iim (const void *iptc, int length, ImageSpec &spec);
1268 
1275 OIIO_API void encode_iptc_iim (const ImageSpec &spec, std::vector<char> &iptc);
1276 
1282 OIIO_API bool decode_xmp (const std::string &xml, ImageSpec &spec);
1283 
1290 OIIO_API std::string encode_xmp (const ImageSpec &spec, bool minimal=false);
1291 
1292 // All the wrap_foo functions implement a wrap mode, wherein coord is
1293 // altered to be origin <= coord < origin+width. The return value
1294 // indicates if the resulting wrapped value is valid (example, for
1295 // wrap_black, values outside the region are invalid and do not modify
1296 // the coord parameter).
1297 OIIO_API bool wrap_black (int &coord, int origin, int width);
1298 OIIO_API bool wrap_clamp (int &coord, int origin, int width);
1299 OIIO_API bool wrap_periodic (int &coord, int origin, int width);
1300 OIIO_API bool wrap_periodic_pow2 (int &coord, int origin, int width);
1301 OIIO_API bool wrap_mirror (int &coord, int origin, int width);
1302 
1303 // Typedef for the function signature of a wrap implementation.
1304 typedef bool (*wrap_impl) (int &coord, int origin, int width);
1305 
1306 
1307 // to force correct linkage on some systems
1308 OIIO_API void _ImageIO_force_link ();
1309 
1310 }
1311 OIIO_NAMESPACE_EXIT
1312 
1313 #endif // OPENIMAGEIO_IMAGEIO_H