blob: 0bd64e41c68761a5891519c7e4da8f0fbb1ed118 [file] [log] [blame]
import '../animation.dart';
import '../image.dart';
import '../hdr/hdr_image.dart';
import '../hdr/hdr_to_image.dart';
import 'decode_info.dart';
import 'decoder.dart';
import 'exr/exr_image.dart';
/// Decode an OpenEXR formatted image.
///
/// OpenEXR is a format developed by Industrial Light & Magic, with collaboration
/// from other companies such as Weta and Pixar, for storing hight dynamic
/// range (HDR) images for use in digital visual effects production. It supports
/// a wide range of features, including 16-bit or 32-bit floating-point channels;
/// lossless and lossy data compression; arbitrary image channels for storing
/// any combination of data, such as red, green, blue, alpha, luminance and
/// chroma channels, depth, surface normal, motion vectors, etc. It can also
/// store images in scanline or tiled format; multiple views for stereo images;
/// multiple parts; etc.
///
/// Because OpenEXR is a high-dynamic-range (HDR) format, it must be converted
/// to a low-dynamic-range (LDR) image for display, or for use as an OpenGL
/// texture (for example). This process is called tone-mapping. Currently only
/// a simple tone-mapping function is provided with a single [exposure]
/// parameter. More tone-mapping functionality will be added.
class ExrDecoder extends Decoder {
ExrImage exrImage;
/// Exposure for tone-mapping the hdr image to an [Image], applied during
/// [decodeFrame].
double exposure;
double gamma;
bool reinhard;
double bloomAmount;
double bloomRadius;
ExrDecoder({this.exposure = 1.0});
bool isValidFile(List<int> data) {
return ExrImage.isValidFile(data);
}
DecodeInfo startDecode(List<int> data) {
exrImage = ExrImage(data);
return exrImage;
}
int numFrames() => exrImage != null ? exrImage.parts.length : 0;
Image decodeFrame(int frame) {
if (exrImage == null) {
return null;
}
return hdrToImage(exrImage.getPart(frame).framebuffer, exposure: exposure);
}
HdrImage decodeHdrFrame(int frame) {
if (exrImage == null) {
return null;
}
if (frame >= exrImage.parts.length) {
return null;
}
return exrImage.parts[frame].framebuffer;
}
Image decodeImage(List<int> bytes, {int frame = 0}) {
if (startDecode(bytes) == null) {
return null;
}
return decodeFrame(frame);
}
HdrImage decodeHdrImage(List<int> bytes, {int frame = 0}) {
if (startDecode(bytes) == null) {
return null;
}
return decodeHdrFrame(frame);
}
Animation decodeAnimation(List<int> data) {
Image image = decodeImage(data);
if (image == null) {
return null;
}
Animation anim = Animation();
anim.width = image.width;
anim.height = image.height;
anim.addFrame(image);
return anim;
}
}