1 /*
2  * Copyright 2016 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #ifndef SkAutoPixmapStorage_DEFINED
9 #define SkAutoPixmapStorage_DEFINED
10 
11 #include "SkPixmap.h"
12 
13 class SK_API SkAutoPixmapStorage : public SkPixmap {
14 public:
15     SkAutoPixmapStorage();
16     ~SkAutoPixmapStorage();
17 
18     /**
19     *  Try to allocate memory for the pixels needed to match the specified Info. On success
20     *  return true and fill out the pixmap to point to that memory. The storage will be freed
21     *  when this object is destroyed, or if another call to tryAlloc() or alloc() is made.
22     *
23     *  On failure, return false and reset() the pixmap to empty.
24     */
25     bool tryAlloc(const SkImageInfo&);
26 
27     /**
28     *  Allocate memory for the pixels needed to match the specified Info and fill out the pixmap
29     *  to point to that memory. The storage will be freed when this object is destroyed,
30     *  or if another call to tryAlloc() or alloc() is made.
31     *
32     *  If the memory cannot be allocated, calls sk_throw().
33     */
34     void alloc(const SkImageInfo&);
35 
36     /**
37     * Gets the size and optionally the rowBytes that would be allocated by SkAutoPixmapStorage if
38     * alloc/tryAlloc was called.
39     */
40     static size_t AllocSize(const SkImageInfo& info, size_t* rowBytes);
41 
42     /**
43     *  Returns an SkData object wrapping the allocated pixels memory, and resets the pixmap.
44     *  If the storage hasn't been allocated, the result is NULL.
45     */
46     const SkData* SK_WARN_UNUSED_RESULT detachPixelsAsData();
47 
48     // We wrap these so we can clear our internal storage
49 
reset()50     void reset() {
51         this->freeStorage();
52         this->INHERITED::reset();
53     }
54     void reset(const SkImageInfo& info, const void* addr, size_t rb, SkColorTable* ctable = NULL) {
55         this->freeStorage();
56         this->INHERITED::reset(info, addr, rb, ctable);
57     }
reset(const SkImageInfo & info)58     void reset(const SkImageInfo& info) {
59         this->freeStorage();
60         this->INHERITED::reset(info);
61     }
reset(const SkMask & mask)62     bool SK_WARN_UNUSED_RESULT reset(const SkMask& mask) {
63         this->freeStorage();
64         return this->INHERITED::reset(mask);
65     }
66 
67 private:
68     void*   fStorage;
69 
freeStorage()70     void freeStorage() {
71         sk_free(fStorage);
72         fStorage = nullptr;
73     }
74 
75     typedef SkPixmap INHERITED;
76 };
77 
78 #endif
79