Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / core / SkMallocPixelRef.cpp
1 /*
2  * Copyright 2011 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 #include "SkMallocPixelRef.h"
9 #include "SkBitmap.h"
10 #include "SkReadBuffer.h"
11 #include "SkWriteBuffer.h"
12
13 // assumes ptr was allocated via sk_malloc
14 static void sk_free_releaseproc(void* ptr, void*) {
15     sk_free(ptr);
16 }
17
18 static bool is_valid(const SkImageInfo& info, SkColorTable* ctable) {
19     if (info.width() < 0 || info.height() < 0 ||
20         (unsigned)info.colorType() > (unsigned)kLastEnum_SkColorType ||
21         (unsigned)info.alphaType() > (unsigned)kLastEnum_SkAlphaType)
22     {
23         return false;
24     }
25
26     // these seem like good checks, but currently we have (at least) tests
27     // that expect the pixelref to succeed even when there is a mismatch
28     // with colortables. fix?
29 #if 0
30     if (kIndex8_SkColorType == info.fColorType && NULL == ctable) {
31         return false;
32     }
33     if (kIndex8_SkColorType != info.fColorType && ctable) {
34         return false;
35     }
36 #endif
37     return true;
38 }
39
40 SkMallocPixelRef* SkMallocPixelRef::NewDirect(const SkImageInfo& info,
41                                               void* addr,
42                                               size_t rowBytes,
43                                               SkColorTable* ctable) {
44     if (!is_valid(info, ctable)) {
45         return NULL;
46     }
47     return SkNEW_ARGS(SkMallocPixelRef,
48                       (info, addr, rowBytes, ctable, NULL, NULL));
49 }
50
51
52 SkMallocPixelRef* SkMallocPixelRef::NewAllocate(const SkImageInfo& info,
53                                                 size_t requestedRowBytes,
54                                                 SkColorTable* ctable) {
55     if (!is_valid(info, ctable)) {
56         return NULL;
57     }
58
59     int32_t minRB = SkToS32(info.minRowBytes());
60     if (minRB < 0) {
61         return NULL;    // allocation will be too large
62     }
63     if (requestedRowBytes > 0 && (int32_t)requestedRowBytes < minRB) {
64         return NULL;    // cannot meet requested rowbytes
65     }
66
67     int32_t rowBytes;
68     if (requestedRowBytes) {
69         rowBytes = SkToS32(requestedRowBytes);
70     } else {
71         rowBytes = minRB;
72     }
73
74     int64_t bigSize = (int64_t)info.height() * rowBytes;
75     if (!sk_64_isS32(bigSize)) {
76         return NULL;
77     }
78
79     size_t size = sk_64_asS32(bigSize);
80     SkASSERT(size >= info.getSafeSize(rowBytes));
81     void* addr = sk_malloc_flags(size, 0);
82     if (NULL == addr) {
83         return NULL;
84     }
85
86     return SkNEW_ARGS(SkMallocPixelRef,
87                       (info, addr, rowBytes, ctable,
88                        sk_free_releaseproc, NULL));
89 }
90
91 SkMallocPixelRef* SkMallocPixelRef::NewWithProc(const SkImageInfo& info,
92                                                 size_t rowBytes,
93                                                 SkColorTable* ctable,
94                                                 void* addr,
95                                                 SkMallocPixelRef::ReleaseProc proc,
96                                                 void* context) {
97     if (!is_valid(info, ctable)) {
98         return NULL;
99     }
100     return SkNEW_ARGS(SkMallocPixelRef,
101                       (info, addr, rowBytes, ctable, proc, context));
102 }
103
104 static void sk_data_releaseproc(void*, void* dataPtr) {
105     (static_cast<SkData*>(dataPtr))->unref();
106 }
107
108 SkMallocPixelRef* SkMallocPixelRef::NewWithData(const SkImageInfo& info,
109                                                 size_t rowBytes,
110                                                 SkColorTable* ctable,
111                                                 SkData* data) {
112     SkASSERT(data != NULL);
113     if (!is_valid(info, ctable)) {
114         return NULL;
115     }
116     if ((rowBytes < info.minRowBytes())
117         || (data->size() < info.getSafeSize(rowBytes))) {
118         return NULL;
119     }
120     data->ref();
121     SkMallocPixelRef* pr
122         = SkNEW_ARGS(SkMallocPixelRef,
123                      (info, const_cast<void*>(data->data()), rowBytes, ctable,
124                       sk_data_releaseproc, static_cast<void*>(data)));
125     SkASSERT(pr != NULL);
126     // We rely on the immutability of the pixels to make the
127     // const_cast okay.
128     pr->setImmutable();
129     return pr;
130 }
131
132 ///////////////////////////////////////////////////////////////////////////////
133
134 SkMallocPixelRef::SkMallocPixelRef(const SkImageInfo& info, void* storage,
135                                    size_t rowBytes, SkColorTable* ctable,
136                                    bool ownsPixels)
137     : INHERITED(info)
138     , fReleaseProc(ownsPixels ? sk_free_releaseproc : NULL)
139     , fReleaseProcContext(NULL) {
140     // This constructor is now DEPRICATED.
141     SkASSERT(is_valid(info, ctable));
142     SkASSERT(rowBytes >= info.minRowBytes());
143
144     if (kIndex_8_SkColorType != info.colorType()) {
145         ctable = NULL;
146     }
147
148     fStorage = storage;
149     fCTable = ctable;
150     fRB = rowBytes;
151     SkSafeRef(ctable);
152
153     this->setPreLocked(fStorage, rowBytes, fCTable);
154 }
155
156 SkMallocPixelRef::SkMallocPixelRef(const SkImageInfo& info, void* storage,
157                                    size_t rowBytes, SkColorTable* ctable,
158                                    SkMallocPixelRef::ReleaseProc proc,
159                                    void* context)
160     : INHERITED(info)
161     , fReleaseProc(proc)
162     , fReleaseProcContext(context)
163 {
164     SkASSERT(is_valid(info, ctable));
165     SkASSERT(rowBytes >= info.minRowBytes());
166
167     if (kIndex_8_SkColorType != info.colorType()) {
168         ctable = NULL;
169     }
170
171     fStorage = storage;
172     fCTable = ctable;
173     fRB = rowBytes;
174     SkSafeRef(ctable);
175
176     this->setPreLocked(fStorage, rowBytes, fCTable);
177 }
178
179
180 SkMallocPixelRef::~SkMallocPixelRef() {
181     SkSafeUnref(fCTable);
182     if (fReleaseProc != NULL) {
183         fReleaseProc(fStorage, fReleaseProcContext);
184     }
185 }
186
187 bool SkMallocPixelRef::onNewLockPixels(LockRec* rec) {
188     rec->fPixels = fStorage;
189     rec->fRowBytes = fRB;
190     rec->fColorTable = fCTable;
191     return true;
192 }
193
194 void SkMallocPixelRef::onUnlockPixels() {
195     // nothing to do
196 }
197
198 size_t SkMallocPixelRef::getAllocatedSizeInBytes() const {
199     return this->info().getSafeSize(fRB);
200 }
201
202 ///////////////////////////////////////////////////////////////////////////////
203
204 SkPixelRef* SkMallocPixelRef::PRFactory::create(const SkImageInfo& info, size_t rowBytes,
205                                                 SkColorTable* ctable) {
206     return SkMallocPixelRef::NewAllocate(info, rowBytes, ctable);
207 }