Skip to content

mmp/tinyexr

 
 

Repository files navigation

Tiny OpenEXR image library.

Example

Build status

tinyexr is a small library to load and save OpenEXR(.exr) images. tinyexr is written in portable C++(no library dependency except for STL), thus tinyexr is good to embed into your application. To use tinyexr, simply copy tinyexr.cc and tinyexr.h into your project.

tinyexr currently supports:

  • OpenEXR version 1.x.
  • Normal image
    • Scanline format.
    • Uncompress("compress" = 0) and ZIP compression("compress" = 3).
    • Half/Uint/Float pixel type.
  • Deep image
    • Scanline format.
    • ZIPS compression("compress" = 2).
    • Half, float pixel type.
  • Litte endian machine.
  • Limited support for big endian machine.
    • read/write normal image.
  • C interface.
    • You can easily write language bindings(e.g. golang)
  • EXR saving
    • with ZIP compression.
  • JavaScript library
    • Through emscripten.

Use case

Usage

Reading ordinal EXR file.

  const char* input = "asakusa.exr";
  float* out; // width * height * RGBA
  int width;
  int height;
  const char* err;

  int ret = LoadEXR(&out, &width, &height, input, &err);

Saving EXR file.

  bool SaveEXR(const float* rgb, int width, int height, const char* outfilename) {

    float* channels[3];

    EXRImage image;

    image.num_channels = 3;

    // Must be BGR(A) order, since most of EXR viewers expect this channel order.
    const char* channel_names[] = {"B", "G", "R"}; // "B", "G", "R", "A" for RGBA image

    std::vector<float> images[3];
    images[0].resize(width * height);
    images[1].resize(width * height);
    images[2].resize(width * height);

    for (int i = 0; i < width * height; i++) {
      images[0][i] = rgb[3*i+0];
      images[1][i] = rgb[3*i+1];
      images[2][i] = rgb[3*i+2];
    }

    float* image_ptr[3];
    image_ptr[0] = &(images[2].at(0)); // B
    image_ptr[1] = &(images[1].at(0)); // G
    image_ptr[2] = &(images[0].at(0)); // R

    image.channel_names = channel_names;
    image.images = image_ptr;
    image.width = gWidth;
    image.height = gHeight;

    for (int i = 0; i < image.num_channels; i++) {
      image.pixel_types[i] = TINYEXR_PIXELTYPE_FLOAT;
    }

    ret = SaveMultiChannelEXRToFile(&image, outfilename, &err);
    if (ret != 0) {
      fprintf(stderr, "Save EXR err: %s\n", err);
      return ret;
    }
    printf("Saved exr file. [ %s ] \n", outfilename);
    return ret;

  }

Reading deep image EXR file. See example/deepview for actual usage.

  const char* input = "deepimage.exr";
  const char* err;
  DeepImage deepImage;

  int ret = LoadDeepEXR(&deepImage, input, &err);

  // acccess to each sample in the deep pixel.
  for (int y = 0; y < deepImage.height; y++) {
    int sampleNum = deepImage.offset_table[y][deepImage.width-1];
    for (int x = 0; x < deepImage.width-1; x++) {
      int s_start = deepImage.offset_table[y][x];
      int s_end   = deepImage.offset_table[y][x+1];
      if (s_start >= sampleNum) {
        continue;
      }
      s_end = (s_end < sampleNum) ? s_end : sampleNum;
      for (int s = s_start; s < s_end; s++) {
        float val = deepImage.image[depthChan][y][s];
        ...
      }
    }
  }

Example

deepview

examples/deepview is simple deep image viewer in OpenGL.

DeepViewExample

TODO

Contribution is welcome!

  • JavaScript library
    • LoadEXRFromMemory
    • SaveMultiChannelEXR
    • Deep image save/load
  • Write from/to memory buffer.
    • SaveMultiChannelEXR
    • LoadMultiChannelEXR
    • Deep image save/load
  • Tile format.
  • Support for various compression type.
  • Multi-channel.
  • Multi-part(EXR2.0)
  • Pixel order.
  • Pixel format(UINT, FLOAT).
    • UINT, FLOAT(load)
    • UINT, FLOAT(deep load)
    • UINT, FLOAT(save)
    • UINT, FLOAT(deep save)
  • Full support for big endian machine.
    • Loading multi channel EXR
    • Saving multi channel EXR
    • Loading deep image
    • Saving deep image
  • Optimization
    • ISPC?
    • OpenMP multi-threading in EXR loading.
    • OpenMP multi-threading in EXR saving.
    • OpenMP multi-threading in deep image loading.
    • OpenMP multi-threading in deep image saving.

Similar projects

License

3-clause BSD

tinyexr uses miniz, which is developed by Rich Geldreich richgel99@gmail.com, and licensed under public domain.

Author(s)

Syoyo Fujita(syoyo@lighttransport.com)

Contributor(s)

About

Tiny OpenEXR image loader/saver library

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C++ 96.8%
  • C 2.6%
  • Other 0.6%