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 is_valid(const SkImageInfo& info, SkColorTable* ctable) { |
13 SkColorTable* ctable, bool ownPixels) { | 13 if (info.fWidth < 0 || |
14 if (NULL == storage) { | 14 info.fHeight < 0 || |
15 SkASSERT(ownPixels); | 15 (unsigned)info.fColorType > (unsigned)kLastEnum_SkColorType || |
16 storage = sk_malloc_throw(size); | 16 (unsigned)info.fAlphaType > (unsigned)kLastEnum_SkAlphaType) |
| 17 { |
| 18 return false; |
17 } | 19 } |
| 20 |
| 21 // these seem like good checks, but currently we have (at least) tests |
| 22 // that expect the pixelref to succeed even when there is a mismatch |
| 23 // with colortables. fix? |
| 24 #if 0 |
| 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 |
| 35 SkMallocPixelRef* SkMallocPixelRef::NewDirect(const SkImageInfo& info, |
| 36 void* addr, |
| 37 size_t rowBytes, |
| 38 SkColorTable* ctable) { |
| 39 if (!is_valid(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 (!is_valid(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 : INHERITED(info) |
| 88 , fOwnPixels(ownsPixels) |
| 89 { |
| 90 SkASSERT(is_valid(info, ctable)); |
| 91 SkASSERT(rowBytes >= info.minRowBytes()); |
| 92 |
| 93 if (kIndex_8_SkColorType != info.fColorType) { |
| 94 ctable = NULL; |
| 95 } |
| 96 |
18 fStorage = storage; | 97 fStorage = storage; |
19 fSize = size; | |
20 fCTable = ctable; | 98 fCTable = ctable; |
| 99 fRB = rowBytes; |
21 SkSafeRef(ctable); | 100 SkSafeRef(ctable); |
22 fOwnPixels = ownPixels; | 101 |
23 | |
24 this->setPreLocked(fStorage, fCTable); | 102 this->setPreLocked(fStorage, fCTable); |
25 } | 103 } |
26 | 104 |
27 SkMallocPixelRef::~SkMallocPixelRef() { | 105 SkMallocPixelRef::~SkMallocPixelRef() { |
28 SkSafeUnref(fCTable); | 106 SkSafeUnref(fCTable); |
29 if (fOwnPixels) { | 107 if (fOwnPixels) { |
30 sk_free(fStorage); | 108 sk_free(fStorage); |
31 } | 109 } |
32 } | 110 } |
33 | 111 |
34 void* SkMallocPixelRef::onLockPixels(SkColorTable** ct) { | 112 void* SkMallocPixelRef::onLockPixels(SkColorTable** ctable) { |
35 *ct = fCTable; | 113 *ctable = fCTable; |
36 return fStorage; | 114 return fStorage; |
37 } | 115 } |
38 | 116 |
39 void SkMallocPixelRef::onUnlockPixels() { | 117 void SkMallocPixelRef::onUnlockPixels() { |
40 // nothing to do | 118 // nothing to do |
41 } | 119 } |
42 | 120 |
| 121 size_t SkMallocPixelRef::getAllocatedSizeInBytes() const { |
| 122 return this->info().getSafeSize(fRB); |
| 123 } |
| 124 |
43 void SkMallocPixelRef::flatten(SkFlattenableWriteBuffer& buffer) const { | 125 void SkMallocPixelRef::flatten(SkFlattenableWriteBuffer& buffer) const { |
44 this->INHERITED::flatten(buffer); | 126 this->INHERITED::flatten(buffer); |
45 | 127 |
46 buffer.writeByteArray(fStorage, fSize); | 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->info().getSafeSize(fRB); |
| 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 fRB = buffer.read32(); |
| 145 size_t size = this->info().getSafeSize(fRB); |
| 146 fStorage = sk_malloc_throw(size); |
| 147 buffer.readByteArray(fStorage, size); |
58 if (buffer.readBool()) { | 148 if (buffer.readBool()) { |
59 fCTable = SkNEW_ARGS(SkColorTable, (buffer)); | 149 fCTable = SkNEW_ARGS(SkColorTable, (buffer)); |
60 } else { | 150 } else { |
61 fCTable = NULL; | 151 fCTable = NULL; |
62 } | 152 } |
63 fOwnPixels = true; | |
64 | 153 |
65 this->setPreLocked(fStorage, fCTable); | 154 this->setPreLocked(fStorage, fCTable); |
66 } | 155 } |
OLD | NEW |