Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1043)

Unified Diff: src/codec/SkExrCodec.cpp

Issue 2344523002: Experimental: EXR
Patch Set: Now we have a decoder Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/codec/SkExrCodec.h ('k') | src/images/SkEXRImageEncoder.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/codec/SkExrCodec.cpp
diff --git a/src/codec/SkExrCodec.cpp b/src/codec/SkExrCodec.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..bea9a63d274216c4afe2443510a2ac40e7727684
--- /dev/null
+++ b/src/codec/SkExrCodec.cpp
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkExrCodec.h"
+
+//#define TINYEXR_IMPLEMENTATION
+#include "tinyexr.h"
+
+bool SkExrCodec::IsExr(const void* buffer, size_t bytes) {
+ static constexpr uint8_t kExrSig[] = { 0x76, 0x2f, 0x31, 0x01, };
+ return bytes >= 4 && 0 == memcmp(buffer, kExrSig, 4);
+}
+
+SkCodec* SkExrCodec::NewFromStream(SkStream* stream) {
+ sk_sp<SkData> data = ((SkMemoryStream*) stream)->asData();
+
+ EXRVersion version;
+ int result = ParseEXRVersionFromMemory(&version, data->bytes(), data->size());
+ if (result != TINYEXR_SUCCESS) {
+ return nullptr;
+ }
+
+ EXRHeader header;
+ InitEXRHeader(&header);
+ result = ParseEXRHeaderFromMemory(&header, &version, data->bytes(), data->size(), nullptr);
+ if (TINYEXR_SUCCESS != result) {
+ return nullptr;
+ }
+
+ int width = header.data_window[2] - header.data_window[0] + 1;
+ int height = header.data_window[3] - header.data_window[1] + 1;
+ SkEncodedInfo info = SkEncodedInfo::Make(SkEncodedInfo::kRGB_Color,
+ SkEncodedInfo::kOpaque_Alpha, 8);
+ return new SkExrCodec(width, height, info, SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named),
+ stream, data);
+}
+
+SkCodec::Result SkExrCodec::onGetPixels(const SkImageInfo& dstInfo, void* dst, size_t rowBytes,
+ const Options& options, SkPMColor*, int*,
+ int* rowsDecodedPtr) {
+ EXRVersion exr_version;
+ EXRImage exr_image;
+ EXRHeader exr_header;
+
+ InitEXRHeader(&exr_header);
+
+ int ret = ParseEXRVersionFromMemory(&exr_version, fData->bytes(), fData->size());
+ if (ret != TINYEXR_SUCCESS) {
+ return kInvalidInput;
+ }
+
+ ret = ParseEXRHeaderFromMemory(&exr_header, &exr_version, fData->bytes(), fData->size(), nullptr);
+ if (ret != TINYEXR_SUCCESS) {
+ return kInvalidInput;
+ }
+
+ int pixelTypes[] = {
+ TINYEXR_PIXELTYPE_FLOAT,
+ TINYEXR_PIXELTYPE_FLOAT,
+ TINYEXR_PIXELTYPE_FLOAT,
+ TINYEXR_PIXELTYPE_FLOAT,
+ };
+ exr_header.requested_pixel_types = pixelTypes;
+
+ InitEXRImage(&exr_image);
+ ret = LoadEXRImageFromMemory(&exr_image, &exr_header, fData->bytes(), nullptr);
+ if (ret != TINYEXR_SUCCESS) {
+ return kInvalidInput;
+ }
+
+ // RGBA
+ int idxR = -1;
+ int idxG = -1;
+ int idxB = -1;
+ for (int c = 0; c < exr_header.num_channels; c++) {
+ if (strcmp(exr_header.channels[c].name, "R") == 0) {
+ idxR = c;
+ } else if (strcmp(exr_header.channels[c].name, "G") == 0) {
+ idxG = c;
+ } else if (strcmp(exr_header.channels[c].name, "B") == 0) {
+ idxB = c;
+ }
+ }
+
+ if (idxR == -1 || idxG == -1 || idxB == -1) {
+ return kInvalidInput;
+ }
+
+ // Assume `out_rgba` have enough memory allocated.
+ uint32_t* dst32 = (uint32_t*) dst;
+ for (int i = 0; i < exr_image.width * exr_image.height; i++) {
+ SkColor4f rgba;
+ rgba.fR = reinterpret_cast<float **>(exr_image.images)[idxR][i];
+ rgba.fG = reinterpret_cast<float **>(exr_image.images)[idxG][i];
+ rgba.fB = reinterpret_cast<float **>(exr_image.images)[idxB][i];
+ rgba.fA = 1.0;
+ //SkDebugf("%g %g %g %g\n", rgba.fR, rgba.fG, rgba.fB, rgba.fA);
+ SkColor color = rgba.toSkColor();
+ dst32[i] = color;
+ }
+
+ return kSuccess;
+}
+
+SkExrCodec::SkExrCodec(int width, int height, const SkEncodedInfo& info,
+ sk_sp<SkColorSpace> colorSpace, SkStream* stream, sk_sp<SkData> data)
+ : INHERITED(width, height, info, stream, std::move(colorSpace))
+ , fData(data)
+{}
« no previous file with comments | « src/codec/SkExrCodec.h ('k') | src/images/SkEXRImageEncoder.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698