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

Unified Diff: blimp/common/compositor/blimp_image_serialization_processor.cc

Issue 1680333004: Add support for encoding/decoding WebP images. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@serialize-deserialize-images-framework
Patch Set: Simplify WebPDecoder and assume premultiplied alpha channel Created 4 years, 10 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
Index: blimp/common/compositor/blimp_image_serialization_processor.cc
diff --git a/blimp/common/compositor/blimp_image_serialization_processor.cc b/blimp/common/compositor/blimp_image_serialization_processor.cc
index 36ea6af38275856c8d91fe02215e0c2b4c2b9db0..6c1032a12903b6eb53e0676eeab1473bfef93dfe 100644
--- a/blimp/common/compositor/blimp_image_serialization_processor.cc
+++ b/blimp/common/compositor/blimp_image_serialization_processor.cc
@@ -8,14 +8,89 @@
#include <vector>
#include "base/logging.h"
+#include "blimp/common/compositor/webp_decoder.h"
+#include "third_party/libwebp/webp/encode.h"
+#include "third_party/skia/include/core/SkData.h"
#include "third_party/skia/include/core/SkPicture.h"
#include "third_party/skia/include/core/SkPixelSerializer.h"
namespace {
-bool NoopDecoder(const void* input, size_t input_size, SkBitmap* bitmap) {
- // TODO(nyquist): Add an image decoder.
- return false;
-}
+// TODO(nyquist): Make sure encoder does not serialize images more than once.
+// See crbug.com/548434.
+class WebPImageEncoder : public SkPixelSerializer {
+ public:
+ WebPImageEncoder() {}
+ ~WebPImageEncoder() override{};
+
+ bool onUseEncodedData(const void* data, size_t len) override {
+ const unsigned char* cast_data = static_cast<const unsigned char*>(data);
+ if (len < 14)
+ return false;
+ return !memcmp(cast_data, "RIFF", 4) && !memcmp(cast_data + 8, "WEBPVP", 6);
+ }
+
+ SkData* onEncode(const SkPixmap& pixmap) override {
+ auto pixel_chars = static_cast<const unsigned char*>(pixmap.addr());
+ WebPConfig config;
+ if (!WebPConfigInit(&config))
+ return nullptr;
+ WebPPicture picture;
+ if (!WebPPictureInit(&picture))
+ return nullptr;
+
+ if (!pixmap.width() || pixmap.width() > WEBP_MAX_DIMENSION)
+ return nullptr;
+ picture.width = pixmap.width();
+ if (!pixmap.height() || pixmap.height() > WEBP_MAX_DIMENSION)
+ return nullptr;
+ picture.height = pixmap.height();
+
+ if (!PlatformImportPicture(pixel_chars, &picture))
+ return nullptr;
+
+ const int quality = 50;
+ std::vector<unsigned char> data;
+ picture.custom_ptr = &data;
+ picture.writer = &WebPImageEncoder::WriteOutput;
+ config.quality = quality;
+ config.method = 3;
+
+ bool success = WebPEncode(&config, &picture);
+ WebPPictureFree(&picture);
+ if (!success)
+ return nullptr;
+ return SkData::NewWithCopy(&data.front(), data.size());
+ }
+
+ private:
+ static int WriteOutput(const uint8_t* data,
+ size_t size,
+ const WebPPicture* const picture) {
+ std::vector<unsigned char>* dest =
+ static_cast<std::vector<unsigned char>*>(picture->custom_ptr);
+ dest->insert(dest->end(), data, data + size);
+ return 1;
+ }
+
+ typedef int (*WebPImporter)(WebPPicture* const,
+ const uint8_t* const data,
+ int row_stride);
+
+ bool RgbPictureImport(const unsigned char* pixels,
+ WebPImporter import_RGBA,
+ WebPPicture* picture) {
+ return import_RGBA(picture, pixels, static_cast<int>(picture->width * 4)) !=
+ 0;
+ }
+
+ bool PlatformImportPicture(const unsigned char* pixels,
+ WebPPicture* picture) {
+ if (SK_B32_SHIFT) // Android
+ return RgbPictureImport(pixels, &WebPPictureImportRGBA, picture);
urvang 2016/02/13 00:24:36 WebPPictureImportRGBA() and WebPPictureImportBGRA(
nyquist 2016/02/16 23:37:10 Always assuming premultiplied, and applying unprem
+
+ return RgbPictureImport(pixels, &WebPPictureImportBGRA, picture);
+ }
+};
} // namespace
@@ -24,12 +99,12 @@ namespace blimp {
BlimpImageSerializationProcessor::BlimpImageSerializationProcessor(Mode mode) {
switch (mode) {
case Mode::SERIALIZATION:
- pixel_serializer_ = nullptr;
+ pixel_serializer_.reset(new WebPImageEncoder);
pixel_deserializer_ = nullptr;
break;
case Mode::DESERIALIZATION:
pixel_serializer_ = nullptr;
- pixel_deserializer_ = &NoopDecoder;
+ pixel_deserializer_ = &WebPDecoder;
break;
default:
NOTREACHED() << "Unknown serialization mode";

Powered by Google App Engine
This is Rietveld 408576698