OLD | NEW |
| 1 |
1 /* | 2 /* |
2 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
3 * | 4 * |
4 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 6 * found in the LICENSE file. |
6 */ | 7 */ |
7 | |
8 #include "SkMallocPixelRef.h" | 8 #include "SkMallocPixelRef.h" |
9 #include "SkBitmap.h" | 9 #include "SkBitmap.h" |
10 #include "SkFlattenableBuffers.h" | 10 #include "SkFlattenableBuffers.h" |
11 | 11 |
12 static bool check_info(const SkImageInfo& info, SkColorTable* ctable) { | 12 SkMallocPixelRef::SkMallocPixelRef(void* storage, size_t size, |
13 if (info.fWidth < 0 || | 13 SkColorTable* ctable, bool ownPixels) { |
14 info.fHeight < 0 || | 14 if (NULL == storage) { |
15 (unsigned)info.fColorType > (unsigned)kLastEnum_SkColorType || | 15 SkASSERT(ownPixels); |
16 (unsigned)info.fAlphaType > (unsigned)kLastEnum_SkAlphaType) | 16 storage = sk_malloc_throw(size); |
17 { | |
18 return false; | |
19 } | 17 } |
20 | 18 fStorage = storage; |
21 // these seem like good checks, but currently we have (at least) tests | 19 fSize = size; |
22 // that expect the pixelref to succeed even when there is a mismatch | 20 fCTable = ctable; |
23 // with colortables. fix? | 21 SkSafeRef(ctable); |
24 #if 0 | 22 fOwnPixels = ownPixels; |
25 if (kIndex8_SkColorType == info.fColorType && NULL == ctable) { | |
26 return false; | |
27 } | |
28 if (kIndex8_SkColorType != info.fColorType && NULL != ctable) { | |
29 return false; | |
30 } | |
31 #endif | |
32 return true; | |
33 } | |
34 | 23 |
35 SkMallocPixelRef* SkMallocPixelRef::NewDirect(const SkImageInfo& info, | 24 this->setPreLocked(fStorage, fCTable); |
36 void* addr, | |
37 size_t rowBytes, | |
38 SkColorTable* ctable) { | |
39 if (!check_info(info, ctable)) { | |
40 return NULL; | |
41 } | |
42 return SkNEW_ARGS(SkMallocPixelRef, (info, addr, rowBytes, ctable, false)); | |
43 } | |
44 | |
45 SkMallocPixelRef* SkMallocPixelRef::NewAllocate(const SkImageInfo& info, | |
46 size_t requestedRowBytes, | |
47 SkColorTable* ctable) { | |
48 if (!check_info(info, ctable)) { | |
49 return NULL; | |
50 } | |
51 | |
52 int32_t minRB = info.minRowBytes(); | |
53 if (minRB < 0) { | |
54 return NULL; // allocation will be too large | |
55 } | |
56 if (requestedRowBytes > 0 && (int32_t)requestedRowBytes < minRB) { | |
57 return NULL; // cannot meet requested rowbytes | |
58 } | |
59 | |
60 int32_t rowBytes; | |
61 if (requestedRowBytes) { | |
62 rowBytes = requestedRowBytes; | |
63 } else { | |
64 rowBytes = minRB; | |
65 } | |
66 | |
67 Sk64 bigSize; | |
68 bigSize.setMul(info.fHeight, rowBytes); | |
69 if (!bigSize.is32()) { | |
70 return NULL; | |
71 } | |
72 | |
73 size_t size = bigSize.get32(); | |
74 void* addr = sk_malloc_flags(size, 0); | |
75 if (NULL == addr) { | |
76 return NULL; | |
77 } | |
78 | |
79 return SkNEW_ARGS(SkMallocPixelRef, (info, addr, rowBytes, ctable, true)); | |
80 } | |
81 | |
82 /////////////////////////////////////////////////////////////////////////////// | |
83 | |
84 SkMallocPixelRef::SkMallocPixelRef(const SkImageInfo& info, void* storage, | |
85 size_t rowBytes, SkColorTable* ctable, | |
86 bool ownsPixels) | |
87 : SkPixelRef(info) | |
88 , fOwnPixels(ownsPixels) | |
89 { | |
90 SkASSERT(check_info(info, ctable)); | |
91 SkASSERT(rowBytes >= info.minRowBytes()); | |
92 | |
93 if (kIndex8_SkColorType != info.fColorType) { | |
94 ctable = NULL; | |
95 } | |
96 | |
97 fStorage = storage; | |
98 fCTable = ctable; | |
99 fRB = rowBytes; | |
100 SkSafeRef(ctable); | |
101 | |
102 this->setPreLocked(fStorage, fRB, fCTable); | |
103 } | 25 } |
104 | 26 |
105 SkMallocPixelRef::~SkMallocPixelRef() { | 27 SkMallocPixelRef::~SkMallocPixelRef() { |
106 SkSafeUnref(fCTable); | 28 SkSafeUnref(fCTable); |
107 if (fOwnPixels) { | 29 if (fOwnPixels) { |
108 sk_free(fStorage); | 30 sk_free(fStorage); |
109 } | 31 } |
110 } | 32 } |
111 | 33 |
112 bool SkMallocPixelRef::onNewLockPixels(LockRec* rec) { | 34 void* SkMallocPixelRef::onLockPixels(SkColorTable** ct) { |
113 rec->fPixels = fStorage; | 35 *ct = fCTable; |
114 rec->fRowBytes = fRB; | 36 return fStorage; |
115 rec->fColorTable = fCTable; | |
116 return true; | |
117 } | 37 } |
118 | 38 |
119 void SkMallocPixelRef::onUnlockPixels() { | 39 void SkMallocPixelRef::onUnlockPixels() { |
120 // nothing to do | 40 // nothing to do |
121 } | 41 } |
122 | 42 |
123 size_t SkMallocPixelRef::getAllocatedSizeInBytes() const { | |
124 return this->info().getSafeSize(fRB); | |
125 } | |
126 | |
127 void SkMallocPixelRef::flatten(SkFlattenableWriteBuffer& buffer) const { | 43 void SkMallocPixelRef::flatten(SkFlattenableWriteBuffer& buffer) const { |
128 this->INHERITED::flatten(buffer); | 44 this->INHERITED::flatten(buffer); |
129 | 45 |
130 buffer.write32(fRB); | 46 buffer.writeByteArray(fStorage, fSize); |
131 | |
132 // TODO: replace this bulk write with a chunky one that can trim off any | |
133 // trailing bytes on each scanline (in case rowbytes > width*size) | |
134 size_t size = this->info().getSafeSize(fRB); | |
135 buffer.writeByteArray(fStorage, size); | |
136 buffer.writeBool(fCTable != NULL); | 47 buffer.writeBool(fCTable != NULL); |
137 if (fCTable) { | 48 if (fCTable) { |
138 fCTable->writeToBuffer(buffer); | 49 fCTable->writeToBuffer(buffer); |
139 } | 50 } |
140 } | 51 } |
141 | 52 |
142 SkMallocPixelRef::SkMallocPixelRef(SkFlattenableReadBuffer& buffer) | 53 SkMallocPixelRef::SkMallocPixelRef(SkFlattenableReadBuffer& buffer) |
143 : INHERITED(buffer, NULL) | 54 : INHERITED(buffer, NULL) { |
144 , fOwnPixels(true) | 55 fSize = buffer.getArrayCount(); |
145 { | 56 fStorage = sk_malloc_throw(fSize); |
146 fRB = buffer.read32(); | 57 buffer.readByteArray(fStorage, fSize); |
147 size_t size = this->info().getSafeSize(fRB); | |
148 fStorage = sk_malloc_throw(size); | |
149 buffer.readByteArray(fStorage, size); | |
150 if (buffer.readBool()) { | 58 if (buffer.readBool()) { |
151 fCTable = SkNEW_ARGS(SkColorTable, (buffer)); | 59 fCTable = SkNEW_ARGS(SkColorTable, (buffer)); |
152 } else { | 60 } else { |
153 fCTable = NULL; | 61 fCTable = NULL; |
154 } | 62 } |
| 63 fOwnPixels = true; |
155 | 64 |
156 this->setPreLocked(fStorage, fRB, fCTable); | 65 this->setPreLocked(fStorage, fCTable); |
157 } | 66 } |
OLD | NEW |