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