1c5035e70cc3fb290f95fd1c052c637aa0dbaf9earobertphillips/*
2c5035e70cc3fb290f95fd1c052c637aa0dbaf9earobertphillips * Copyright 2016 Google Inc.
3c5035e70cc3fb290f95fd1c052c637aa0dbaf9earobertphillips *
4c5035e70cc3fb290f95fd1c052c637aa0dbaf9earobertphillips * Use of this source code is governed by a BSD-style license that can be
5c5035e70cc3fb290f95fd1c052c637aa0dbaf9earobertphillips * found in the LICENSE file.
6c5035e70cc3fb290f95fd1c052c637aa0dbaf9earobertphillips */
7c5035e70cc3fb290f95fd1c052c637aa0dbaf9earobertphillips
8c5035e70cc3fb290f95fd1c052c637aa0dbaf9earobertphillips#include "SkAutoPixmapStorage.h"
9c5035e70cc3fb290f95fd1c052c637aa0dbaf9earobertphillips#include "SkData.h"
10c5035e70cc3fb290f95fd1c052c637aa0dbaf9earobertphillips
11c5035e70cc3fb290f95fd1c052c637aa0dbaf9earobertphillipsSkAutoPixmapStorage::SkAutoPixmapStorage() : fStorage(nullptr) {}
12c5035e70cc3fb290f95fd1c052c637aa0dbaf9earobertphillips
13c5035e70cc3fb290f95fd1c052c637aa0dbaf9earobertphillipsSkAutoPixmapStorage::~SkAutoPixmapStorage() {
14c5035e70cc3fb290f95fd1c052c637aa0dbaf9earobertphillips    this->freeStorage();
15c5035e70cc3fb290f95fd1c052c637aa0dbaf9earobertphillips}
16c5035e70cc3fb290f95fd1c052c637aa0dbaf9earobertphillips
177a8c84c6c92565842aeea27d4971fbd78d523f7aEric KarlSkAutoPixmapStorage& SkAutoPixmapStorage::operator=(SkAutoPixmapStorage&& other) {
187a8c84c6c92565842aeea27d4971fbd78d523f7aEric Karl    this->fStorage = other.fStorage;
19086a427b0cee3862f25c492fc5082ff24105dc53Mike Reed    this->INHERITED::reset(other.info(), this->fStorage, other.rowBytes());
207a8c84c6c92565842aeea27d4971fbd78d523f7aEric Karl
217a8c84c6c92565842aeea27d4971fbd78d523f7aEric Karl    other.fStorage = nullptr;
227a8c84c6c92565842aeea27d4971fbd78d523f7aEric Karl    other.INHERITED::reset();
237a8c84c6c92565842aeea27d4971fbd78d523f7aEric Karl
247a8c84c6c92565842aeea27d4971fbd78d523f7aEric Karl    return *this;
257a8c84c6c92565842aeea27d4971fbd78d523f7aEric Karl}
267a8c84c6c92565842aeea27d4971fbd78d523f7aEric Karl
27c5035e70cc3fb290f95fd1c052c637aa0dbaf9earobertphillipssize_t SkAutoPixmapStorage::AllocSize(const SkImageInfo& info, size_t* rowBytes) {
28c5035e70cc3fb290f95fd1c052c637aa0dbaf9earobertphillips    size_t rb = info.minRowBytes();
29c5035e70cc3fb290f95fd1c052c637aa0dbaf9earobertphillips    if (rowBytes) {
30c5035e70cc3fb290f95fd1c052c637aa0dbaf9earobertphillips        *rowBytes = rb;
31c5035e70cc3fb290f95fd1c052c637aa0dbaf9earobertphillips    }
32f0ffb8943b7be477b769db23660a80013f3332ebMike Reed    return info.computeByteSize(rb);
33c5035e70cc3fb290f95fd1c052c637aa0dbaf9earobertphillips}
34c5035e70cc3fb290f95fd1c052c637aa0dbaf9earobertphillips
35c5035e70cc3fb290f95fd1c052c637aa0dbaf9earobertphillipsbool SkAutoPixmapStorage::tryAlloc(const SkImageInfo& info) {
36c5035e70cc3fb290f95fd1c052c637aa0dbaf9earobertphillips    this->freeStorage();
37c5035e70cc3fb290f95fd1c052c637aa0dbaf9earobertphillips
38c5035e70cc3fb290f95fd1c052c637aa0dbaf9earobertphillips    size_t rb;
39c5035e70cc3fb290f95fd1c052c637aa0dbaf9earobertphillips    size_t size = AllocSize(info, &rb);
40c5eb97dd8875accf2b5db5343dace78d0d4c6f79Mike Reed    if (SkImageInfo::ByteSizeOverflowed(size)) {
41c5035e70cc3fb290f95fd1c052c637aa0dbaf9earobertphillips        return false;
42c5035e70cc3fb290f95fd1c052c637aa0dbaf9earobertphillips    }
438dc8dbc8211e7b0245a6e7db911265efbe0fccafMike Reed    void* pixels = sk_malloc_canfail(size);
44c5035e70cc3fb290f95fd1c052c637aa0dbaf9earobertphillips    if (nullptr == pixels) {
45c5035e70cc3fb290f95fd1c052c637aa0dbaf9earobertphillips        return false;
46c5035e70cc3fb290f95fd1c052c637aa0dbaf9earobertphillips    }
47c5035e70cc3fb290f95fd1c052c637aa0dbaf9earobertphillips    this->reset(info, pixels, rb);
48c5035e70cc3fb290f95fd1c052c637aa0dbaf9earobertphillips    fStorage = pixels;
49c5035e70cc3fb290f95fd1c052c637aa0dbaf9earobertphillips    return true;
50c5035e70cc3fb290f95fd1c052c637aa0dbaf9earobertphillips}
51c5035e70cc3fb290f95fd1c052c637aa0dbaf9earobertphillips
52c5035e70cc3fb290f95fd1c052c637aa0dbaf9earobertphillipsvoid SkAutoPixmapStorage::alloc(const SkImageInfo& info) {
537ca9a74fef3296cdf1385785b5e817e963bb4c35Ben Wagner    SkASSERT_RELEASE(this->tryAlloc(info));
54c5035e70cc3fb290f95fd1c052c637aa0dbaf9earobertphillips}
55c5035e70cc3fb290f95fd1c052c637aa0dbaf9earobertphillips
56c5035e70cc3fb290f95fd1c052c637aa0dbaf9earobertphillipsconst SkData* SkAutoPixmapStorage::detachPixelsAsData() {
57c5035e70cc3fb290f95fd1c052c637aa0dbaf9earobertphillips    if (!fStorage) {
58c5035e70cc3fb290f95fd1c052c637aa0dbaf9earobertphillips        return nullptr;
59c5035e70cc3fb290f95fd1c052c637aa0dbaf9earobertphillips    }
60c5035e70cc3fb290f95fd1c052c637aa0dbaf9earobertphillips
61f0ffb8943b7be477b769db23660a80013f3332ebMike Reed    auto data = SkData::MakeFromMalloc(fStorage, this->computeByteSize());
62c5035e70cc3fb290f95fd1c052c637aa0dbaf9earobertphillips    fStorage = nullptr;
63c5035e70cc3fb290f95fd1c052c637aa0dbaf9earobertphillips    this->INHERITED::reset();
64c5035e70cc3fb290f95fd1c052c637aa0dbaf9earobertphillips
65c5035e70cc3fb290f95fd1c052c637aa0dbaf9earobertphillips    return data.release();
66c5035e70cc3fb290f95fd1c052c637aa0dbaf9earobertphillips}
67