blob: 5d68c1dccdcde950ca3e8105cdb6f97aa0ba70e9 [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/thumbnails/thumbnail_image.h"
#include <utility>
#include "base/task/post_task.h"
#include "base/task/task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "ui/gfx/codec/jpeg_codec.h"
// Refcounted class that stores compressed JPEG data.
class ThumbnailImage::ThumbnailData
: public base::RefCountedThreadSafe<ThumbnailData> {
public:
static gfx::ImageSkia ToImageSkia(
scoped_refptr<ThumbnailData> representation) {
const auto& data = representation->data_;
gfx::ImageSkia result = gfx::ImageSkia::CreateFrom1xBitmap(
*gfx::JPEGCodec::Decode(data.data(), data.size()));
result.MakeThreadSafe();
return result;
}
static scoped_refptr<ThumbnailData> FromSkBitmap(SkBitmap bitmap) {
constexpr int kCompressionQuality = 97;
std::vector<uint8_t> data;
const bool result =
gfx::JPEGCodec::Encode(bitmap, kCompressionQuality, &data);
DCHECK(result);
return scoped_refptr<ThumbnailData>(new ThumbnailData(std::move(data)));
}
size_t size() const { return data_.size(); }
private:
friend base::RefCountedThreadSafe<ThumbnailData>;
explicit ThumbnailData(std::vector<uint8_t>&& data)
: data_(std::move(data)) {}
~ThumbnailData() = default;
std::vector<uint8_t> data_;
DISALLOW_COPY_AND_ASSIGN(ThumbnailData);
};
ThumbnailImage::ThumbnailImage() = default;
ThumbnailImage::~ThumbnailImage() = default;
ThumbnailImage::ThumbnailImage(const ThumbnailImage& other) = default;
ThumbnailImage::ThumbnailImage(ThumbnailImage&& other) = default;
ThumbnailImage& ThumbnailImage::operator=(const ThumbnailImage& other) =
default;
ThumbnailImage& ThumbnailImage::operator=(ThumbnailImage&& other) = default;
gfx::ImageSkia ThumbnailImage::AsImageSkia() const {
return ThumbnailData::ToImageSkia(image_representation_);
}
bool ThumbnailImage::AsImageSkiaAsync(AsImageSkiaCallback callback) const {
if (!HasData())
return false;
base::PostTaskWithTraitsAndReplyWithResult(
FROM_HERE,
{base::TaskPriority::USER_VISIBLE,
base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
base::BindOnce(&ThumbnailData::ToImageSkia, image_representation_),
std::move(callback));
return true;
}
bool ThumbnailImage::HasData() const {
return static_cast<bool>(image_representation_);
}
size_t ThumbnailImage::GetStorageSize() const {
return image_representation_ ? image_representation_->size() : 0;
}
bool ThumbnailImage::BackedBySameObjectAs(const ThumbnailImage& other) const {
return image_representation_.get() == other.image_representation_.get();
}
// static
ThumbnailImage ThumbnailImage::FromSkBitmap(SkBitmap bitmap) {
ThumbnailImage result;
result.image_representation_ = ThumbnailData::FromSkBitmap(bitmap);
return result;
}
// static
void ThumbnailImage::FromSkBitmapAsync(SkBitmap bitmap,
CreateThumbnailCallback callback) {
base::PostTaskWithTraitsAndReplyWithResult(
FROM_HERE,
{base::TaskPriority::USER_VISIBLE,
base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
base::BindOnce(&ThumbnailData::FromSkBitmap, bitmap),
base::BindOnce(
[](CreateThumbnailCallback callback,
scoped_refptr<ThumbnailData> representation) {
ThumbnailImage result;
result.image_representation_ = representation;
std::move(callback).Run(result);
},
std::move(callback)));
}