• Stars
    star
    126
  • Rank 284,543 (Top 6 %)
  • Language
    C
  • License
    MIT License
  • Created about 8 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Header-only Tiny DNG/TIFF loader and writer in C++

Tiny DNG Loader and Writer library

Header-only simple&limited DNG(Digital NeGative, TIFF format + extension) loader and writer in C++11.

Currently TinyDNG only supports lossless RAW DNG and limited lossless JPEG DNG(no lossy compression support).

TinyDNG can also be used as an TIFF RGB image loader(8bit, 16bit and 32bit are supported).

TinyDNG loader module is being fuzz tested using LLVMFuzzer, and is enoughly secure(and no C++ exception and assert/abort code exists).

(NOTE: TinyDNG just loads DNG data as is, thus you'll need your own RAW processing code(e.g. debayer) to get a developed image as shown the above)

Features

Loading

  • RAW DNG data
  • Lossless JPEG
  • ZIP-compressed DNG
    • Use miniz or zlib
  • JPEG
    • Support JPEG image(e.g. thumbnail) through stb_image.h.
  • TIFF
    • 8bit uncompressed
    • 8bit LZW compressed(no preditor, horizontal diff predictor)
  • Experimental
    • Apple ProRAW(Lossless JPEG 12bit)
      • Lossless JPEG 12bit
      • Semantic map(8bit Standard JPEG)
    • Decode Canon RAW(CR2)
      • RAW
      • mRAW
      • sRAW
    • Decode Nikon RAW(NEF)
      • TODO
    • Reading custom TIFF tags.
  • Read DNG data from memory.

Writing

  • DNG and TIFF
    • LosslessJPEG compression

Supported DNG files

Here is the list of supported DNG files.

  • Sigma sd Quattro H
    • Uncompressed RGB 12bit image.
  • iPhone DNG
  • Apple ProRAW
    • Lossless JPEG 12bit
    • Semantic map
  • Black magic DNG
    • CinemaDNG(lossy compression) is not supported.
  • Canon CR2(experimental)
  • Magic lantern DNG
  • 8-bit TIFF image
    • LZW compressed 8-bit image.
  • 16-bit uncompressed TIFF image
  • 32-bit uncompressed TIFF image
  • OpCodeList
    • GainMap

Usage

Loading DNG

#include <cstdio>
#include <cstdlib>
#include <iostream>

// Define TINY_DNG_LOADER_IMPLEMENTATION and STB_IMAGE_IMPLEMENTATION in only one *.cc
#define TINY_DNG_LOADER_IMPLEMENTATION
#define STB_IMAGE_IMPLEMENTATION

// Enable ZIP compression(through miniz library)
// Please don't forget copying&adding `miniz.c` and `miniz.h` to your project.
// #define TINY_DNG_LOADER_ENABLE_ZIP

// Uncomment these two lines if you want to use system provided zlib library, not miniz
// #define TINY_DNG_LOADER_USE_SYSTEM_ZLIB
// #include <zlib.h>
#include "tiny_dng_loader.h"

int main(int argc, char **argv) {
  std::string input_filename = "colorchart.dng";

  if (argc > 1) {
    input_filename = std::string(argv[1]);
  }

  std::string warn, err;
  std::vector<tinydng::DNGImage> images;

  // List of custom field infos. This is optional and can be empty.
  std::vector<tinydng::FieldInfo> custom_field_lists;

  // Loads all images(IFD) in the DNG file to `images` array.
  // You can use `LoadDNGFromMemory` API to load DNG image from a memory.
  bool ret = tinydng::LoadDNG(input_filename.c_str(), custom_field_lists, &images, &warn, &err);


  if (!warn.empty()) {
    std::cout << "Warn: " << warn << std::endl;
  }

  if (!err.empty()) {
    std::cerr << "Err: " << err << std::endl;
  }

  if (ret) {
    for (size_t i = 0; i < images.size(); i++) {
      const tinydng::DNGImage &image = images[i];
;
      std::cout << "width = " << image.width << std::endl;
      std::cout << "height = " << image.height << std::endl;
      std::cout << "bits per piexl = " << image.bits_per_sample << std::endl;
      std::cout << "bits per piexl(original) = " << image.bits_per_sample_original << std::endl;
      std::cout << "samples per pixel = " << image.samples_per_pixel << std::endl;

    }
  }

  return EXIT_SUCCESS;
}

Writing DNG(and TIFF)

See examples/dngwriter and https://github.com/storyboardcreativity/zraw-decoder for more details.

#include <cassert>
#include <cstdio>
#include <cstdlib>
#include <iostream>

#define TINY_DNG_WRITER_IMPLEMENTATION
#include "tiny_dng_writer.h"

static void CreateRGBImage(tinydngwriter::DNGImage *dng_image,
                        const unsigned short basecol) {
  unsigned int image_width = 512;
  unsigned int image_height = 512;
  dng_image->SetSubfileType(false, false, false);
  dng_image->SetImageWidth(image_width);
  dng_image->SetImageLength(image_height);
  dng_image->SetRowsPerStrip(image_height);

  // SetSamplesPerPixel must be called before SetBitsPerSample()
  dng_image->SetSamplesPerPixel(3);
  uint16_t bps[3] = {16, 16, 16};
  dng_image->SetBitsPerSample(3, bps);
  dng_image->SetPlanarConfig(tinydngwriter::PLANARCONFIG_CONTIG);
  dng_image->SetCompression(tinydngwriter::COMPRESSION_NONE);
  dng_image->SetPhotometric(tinydngwriter::PHOTOMETRIC_RGB);
  dng_image->SetXResolution(1.0);
  dng_image->SetYResolution(1.2); // fractioal test
  dng_image->SetResolutionUnit(tinydngwriter::RESUNIT_NONE);
  dng_image->SetImageDescription("bora");

  std::vector<unsigned short> buf;
  buf.resize(image_width * image_height * 3);

  for (size_t y = 0; y < image_height; y++) {
    for (size_t x = 0; x < image_width; x++) {
      buf[3 * (y * image_width + x) + 0] = static_cast<unsigned short>(x % 512);
      buf[3 * (y * image_width + x) + 1] = static_cast<unsigned short>(y % 512);
      buf[3 * (y * image_width + x) + 2] = basecol;
    }
  }

  dng_image->SetImageData(reinterpret_cast<unsigned char *>(buf.data()),
                          buf.size() * sizeof(unsigned short));
}

int main(int argc, char **argv) {
  std::string output_filename = "output.dng";

  if (argc < 1) {
    std::cout << argv[0] << " <output.dng>" << std::endl;
  }

  if (argc > 1) {
    output_filename = std::string(argv[1]);
  }

  // TinyDNGWriter supports both BigEndian and LittleEndian TIFF.
  // Default = BigEndian.
  bool big_endian = false;

  if (argc > 2) {
    big_endian = bool(atoi(argv[2]));
  }

  {
    // DNGWriter supports multiple DNG images.
    // First create DNG image data, then pass it to DNGWriter with AddImage API.
    tinydngwriter::DNGImage dng_image0;
    dng_image0.SetBigEndian(big_endian);
    tinydngwriter::DNGImage dng_image1;
    dng_image1.SetBigEndian(big_endian);

    CreateRGBImage(&dng_image0, 12000);
    CreateRGBImage(&dng_image1, 42000);

    tinydngwriter::DNGWriter dng_writer(big_endian);
    bool ret = dng_writer.AddImage(&dng_image0);
    assert(ret);

    ret = dng_writer.AddImage(&dng_image1);
    assert(ret);

    std::string err;
    ret = dng_writer.WriteToFile(output_filename.c_str(), &err);

    if (!err.empty()) {
      std::cerr << err;
    }

    if (!ret) {
      return EXIT_FAILURE;
    }

    std::cout << "Wrote : " << output_filename << std::endl;
  }

  return EXIT_SUCCESS;
}

Customizations

  • TINY_DNG_LOADER_USE_THREAD : Enable threaded loading(requires C++11)
  • TINY_DNG_LOADER_ENABLE_ZIP : Enable decoding AdobeDeflate image(Currently, tiled RGB image only).
    • TINY_DNG_LOADER_USE_SYSTEM_ZLIB : Use system's zlib library instead of miniz.
  • TINY_DNG_LOADER_DEBUG : Enable debug printf(developer only!)
  • TINY_DNG_LOADER_NO_STB_IMAGE_INCLUDE : Do not include stb_image.h inside of tiny_dng_loader.h.
  • TINY_DNG_LOADER_NO_STDIO : Disable printf, cout/cerr.

Examples

Python binding(Experimental)

Build native module.

Install pybind11.

$ python -m pip install pybind11

Then,

$ python setup.py build

or

$ python -m pip install build
$ python -m build .

Currently no PyPI package is available.

See experimental/python for sample python code.

Fuzzing test

Resource

Here is the list of great articles on how to decode RAW file and how to develop RAW image.

TODO

  • Move to C++11.
    • Drop C++03 support.
  • Parse semantic map tags in Apple ProRAW.
  • Add DNG header load only mode
  • Parse more DNG headers
  • Parse more custom DNG(TIFF) tags
  • lossy DNG
  • Improve DNG writer
    • Support compression(LJPEG)
  • Support Big TIFF(4GB+)
  • Decode Nikon RAW(NEF)
  • Improve Canon RAW decoding
  • Optimimze lossless JPEG decoding
  • Delayed load of tiled image.

License

TinyDNG is licensed under MIT license.

TinyDNG uses the following third party libraries.

  • liblj92(Lossless JPEG library) : (c) Andrew Baldwin 2014. MIT license. https://bitbucket.org/baldand/mlrawviewer.git
  • stb_image : Public domain image loader.
  • lzw.hpp : Author: Guilherme R. Lampert. Public domain LZW decoder.
  • miniz : Copyright 2013-2014 RAD Game Tools and Valve Software. Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC MIT license. See miniz.LICENSE

More Repositories

1

tinygltf

Header only C++11 tiny glTF 2.0 library
C++
1,582
star
2

tinyexr

Tiny OpenEXR image loader/saver library
C++
620
star
3

tinyobjloader-c

Header only tiny wavefront .obj loader in pure C99
C
346
star
4

tinyusdz

Tiny, dependency-free USDZ/USDA/USDC library written in C++14
C++
283
star
5

tinygltfloader

Header only C++ Tiny glTF loader.
C
247
star
6

MMDLoader

Simple MMD(PMD/VMD) loader in C++
C++
105
star
7

lucille

lucille global illumination renderer
C
89
star
8

tacotron-tts-cpp

Tacotron text to speech in C++(synthesize only)
C++
71
star
9

nanovg-nanort

NanoRT(SW ray tracer) backend for NanoVG
C
49
star
10

nanocanvas

NanoCanvas, portable JavaScript vector graphics engine.
C
43
star
11

tinymeshutils

Tiny Mesh utilities(e.g. compute half-edge data structure) in C++11
C++
35
star
12

docker-utils

Docker utilities
Shell
33
star
13

tinyvdbio

TinyVDBIO header-only C++ OpenVDB IO library
C++
32
star
14

eson

ESON, Exa-scale Storage Object Notation
Python
31
star
15

window-bootstrap

Cross-platform C++ Window/UI bootstrap
C
29
star
16

python-rdma-examples

Python RDMA sample scripts
Python
18
star
17

tinyshrot

TinySHRot, header-only C89 spherical harmonics rotation codes.
C
17
star
18

aobench

Automatically exported from code.google.com/p/aobench
HTML
16
star
19

aobench_cs

aobench in OpenGL compute shader!
C++
12
star
20

standalone-pocketfft

pocketfft in standalone C
C
12
star
21

tinyxpd

Dependency-free and header-only C++11 XGen XPD cache I/O library.
C++
11
star
22

USD-build-aarch64

USD build script for aarch64 target
C++
10
star
23

dynamic_bitset

Simple dynamic bitset template class
C++
10
star
24

oi-build

OpenIndiana Unified Build System
C
9
star
25

minioptix

Mini OptiX sample
C
8
star
26

libphm

PHM: Simple Portable Half float(fp16) Map fileformat in C/C++
C
7
star
27

tinylinalg

Tiny linear algebra and matrix math library
7
star
28

xgen-spline-to-cyhair

XGen Interactive Grooming spline to CyHair exporter
C++
7
star
29

node.rdma

RDMA transport layer for node.js
C++
6
star
30

tinylosslessjpeg

Tiny LosslessJPEG decoder in C++11
6
star
31

flutter_native_vulkan_experiment

Experiment to call Vulkan function from Flutter(dart ffi)
Dart
6
star
32

espnet-tts-streamlit

ESPNet TTS with Streamlit GUI
Python
6
star
33

tinycolorio

Header-only C++11 color IO library
Jupyter Notebook
6
star
34

OpenVDB-Android

Android port of OpenVDB
C++
5
star
35

staticstruct

Simple statically typed struct serialization/deserialization library in C++11
C++
5
star
36

raw-images

RAW photo images
5
star
37

espnet-tts

ESPNet TTS standalone execution
Python
4
star
38

mudalang

MUDA(MUltiple Data Accelerator) language
Haskell
4
star
39

solaris-infiniband-tools

Tcl
4
star
40

minijit

Minimal clang/LLVM JIT experiment
CMake
4
star
41

usda-to-usdc-experiment

USDA to USDC conversion experiment in C++
C++
4
star
42

cycles

cycles experimental
C++
3
star
43

tinyarchive

Tiny binary archive library.
C++
3
star
44

parallella-playground

Parallella Epiphany playground
C
3
star
45

aobench_oculus

aobench for Oculus Rift
C++
3
star
46

libtorch_mobile_build

libtorch mobile build script
CMake
2
star
47

libjsonnet-cpp

Embed jsonnet to your C++11 application
C++
2
star
48

francine

Render backend
2
star
49

MUDA

MUDA is a MUltiple Data Accleleration language
Haskell
2
star
50

cmake-rpath-experiment

CMake + RPATH experiment
CMake
2
star
51

alembic-converters

Alembic file formart converters in C++11
C++
2
star
52

jsmuda

optimized code generator written in node.js
JavaScript
2
star
53

llvm-project-mingw-build

llvm-project MinGW build script using llvm-mingw
Shell
2
star
54

LLL

Lucille Light transport Language
Haskell
2
star
55

cyhair-combiner

Simple CyHair combiner tool
C++
2
star
56

jch-vis

Visualize Jump Consistent Hash
1
star
57

visemenet-docker

Run VisnemeNet inference in nvidia-docker container
Dockerfile
1
star
58

klee-avx

avx support branch for klee
1
star
59

OSOgraph

Simple script visualizing OSO instructions using graphviz
Python
1
star
60

orelatex

俺得 latex 環境テンプレート
1
star
61

oremake

oremake
JavaScript
1
star
62

aobench-fortran

Fortran 90 port of aobench
Fortran
1
star
63

aobench-osv

OSv port of aobench
C++
1
star
64

nanostl

NanoSTL, small subset of C++ STL
1
star
65

llvm-win-build

llvm-win-build
1
star
66

aobench-ios

aobench-ios
C
1
star
67

orevfx

ore vfx tool build
1
star
68

clapack-cmake-android-arm64

clapack cmake build for Android ARM64(NDK r20 or later)
C
1
star
69

orebuildenv

俺得ビルド環境
Shell
1
star
70

naiad-tools

Naiad emp processing tools
C
1
star
71

lesh

continuos building tool
JavaScript
1
star