Chromium Code Reviews| Index: src/core/SkMallocPixelRef.cpp |
| diff --git a/src/core/SkMallocPixelRef.cpp b/src/core/SkMallocPixelRef.cpp |
| index f229e9de34d0fa8dbdd29304dd0ac0f7a78e5611..0507ba02046f3708f05321da3307464b6ce29b44 100644 |
| --- a/src/core/SkMallocPixelRef.cpp |
| +++ b/src/core/SkMallocPixelRef.cpp |
| @@ -1,27 +1,99 @@ |
| - |
| /* |
| * Copyright 2011 Google Inc. |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| + |
| #include "SkMallocPixelRef.h" |
| #include "SkBitmap.h" |
| #include "SkFlattenableBuffers.h" |
| -SkMallocPixelRef::SkMallocPixelRef(void* storage, size_t size, |
| - SkColorTable* ctable, bool ownPixels) { |
| - if (NULL == storage) { |
| - SkASSERT(ownPixels); |
| - storage = sk_malloc_throw(size); |
| +static bool check_info(const SkImageInfo& info, SkColorTable* ctable) { |
| + if (!info.isValid()) { |
| + return false; |
| + } |
| + |
| + // these seem like good checks, but currently we have (at least) tests |
| + // that expect the pixelref to succeed even when there is a mismatch |
| + // with colortables. fix? |
| +#if 0 |
| + if (kIndex8_SkColorType == info.fColorType && NULL == ctable) { |
| + return false; |
| + } |
| + if (kIndex8_SkColorType != info.fColorType && NULL != ctable) { |
| + return false; |
| + } |
| +#endif |
| + return true; |
| +} |
| + |
| +SkMallocPixelRef* SkMallocPixelRef::Create(const SkImageInfo& info, void* addr, |
| + size_t rowBytes, SkColorTable* ctable) { |
| + if (!check_info(info, ctable)) { |
| + return NULL; |
| + } |
| + return SkNEW_ARGS(SkMallocPixelRef, (info, addr, rowBytes, ctable, false)); |
| +} |
| + |
| +SkMallocPixelRef* SkMallocPixelRef::Allocate(const SkImageInfo& info, |
| + size_t requestedRowBytes, |
| + SkColorTable* ctable) { |
| + if (!check_info(info, ctable)) { |
| + return NULL; |
| + } |
| + |
| + int32_t minRB = info.minRowBytes(); |
| + if (minRB < 0) { |
| + return NULL; // allocation will be too large |
| + } |
| + if (requestedRowBytes > 0 && (int32_t)requestedRowBytes < minRB) { |
| + return NULL; // cannot meet requested rowbytes |
| + } |
| + |
| + int32_t rowBytes; |
| + if (requestedRowBytes) { |
| + rowBytes = requestedRowBytes; |
| + } else { |
| + rowBytes = minRB; |
| + } |
| + |
| + Sk64 bigSize; |
| + bigSize.setMul(info.fHeight, rowBytes); |
| + if (!bigSize.is32()) { |
| + return NULL; |
| + } |
| + |
| + size_t size = bigSize.get32(); |
| + void* addr = sk_malloc_flags(size, 0); |
| + if (NULL == addr) { |
| + return NULL; |
| } |
| + |
| + return SkNEW_ARGS(SkMallocPixelRef, (info, addr, rowBytes, ctable, true)); |
| +} |
| + |
| +/////////////////////////////////////////////////////////////////////////////// |
| + |
| +SkMallocPixelRef::SkMallocPixelRef(const SkImageInfo& info, void* storage, |
| + size_t rowBytes, SkColorTable* ctable, |
| + bool ownsPixels) |
| + : fOwnPixels(ownsPixels) |
| +{ |
|
scroggo
2013/11/20 21:04:28
Brace should be on previous line.
reed1
2013/11/20 21:27:18
I am increasingly finding that much harder to read
scroggo
2013/11/20 21:35:19
Agreed! I think we should update the style guide i
|
| + SkASSERT(check_info(info, ctable)); |
| + SkASSERT(rowBytes >= info.minRowBytes()); |
| + |
| + if (kIndex8_SkColorType != info.fColorType) { |
| + ctable = NULL; |
| + } |
| + |
| fStorage = storage; |
| - fSize = size; |
| fCTable = ctable; |
| + fRB = rowBytes; |
| + fInfo = info; |
| SkSafeRef(ctable); |
| - fOwnPixels = ownPixels; |
| - |
| - this->setPreLocked(fStorage, fCTable); |
| + |
| + this->setPreLocked(fStorage, fRB, fCTable); |
| } |
| SkMallocPixelRef::~SkMallocPixelRef() { |
| @@ -31,7 +103,10 @@ SkMallocPixelRef::~SkMallocPixelRef() { |
| } |
| } |
| -void* SkMallocPixelRef::onLockPixels(SkColorTable** ct) { |
| +void* SkMallocPixelRef::onLockPixels(SkImageInfo* info, size_t* rowBytes, |
| + SkColorTable** ct) { |
| + *info = fInfo; |
| + *rowBytes = fRB; |
| *ct = fCTable; |
| return fStorage; |
| } |
| @@ -43,7 +118,16 @@ void SkMallocPixelRef::onUnlockPixels() { |
| void SkMallocPixelRef::flatten(SkFlattenableWriteBuffer& buffer) const { |
| this->INHERITED::flatten(buffer); |
| - buffer.writeByteArray(fStorage, fSize); |
| + buffer.write32(fInfo.fWidth); |
| + buffer.write32(fInfo.fHeight); |
| + buffer.write32(fInfo.fAlphaType); |
| + buffer.write32(fInfo.fColorType); |
| + buffer.write32(fRB); |
| + |
| + // TODO: replace this bulk write with a chunky one that can trim off any |
| + // trailing bytes on each scanline (in case rowbytes > width*size) |
| + size_t size = this->computeMinSize(); |
| + buffer.writeByteArray(fStorage, size); |
| buffer.writeBool(fCTable != NULL); |
| if (fCTable) { |
| fCTable->writeToBuffer(buffer); |
| @@ -51,16 +135,23 @@ void SkMallocPixelRef::flatten(SkFlattenableWriteBuffer& buffer) const { |
| } |
| SkMallocPixelRef::SkMallocPixelRef(SkFlattenableReadBuffer& buffer) |
| - : INHERITED(buffer, NULL) { |
| - fSize = buffer.getArrayCount(); |
| - fStorage = sk_malloc_throw(fSize); |
| - buffer.readByteArray(fStorage, fSize); |
| + : INHERITED(buffer, NULL) |
| + , fOwnPixels(true) |
| +{ |
|
scroggo
2013/11/20 21:04:28
brace should be on previous line.
|
| + fInfo.fWidth = buffer.read32(); |
| + fInfo.fHeight = buffer.read32(); |
| + fInfo.fAlphaType = (SkAlphaType)buffer.read32(); |
| + fInfo.fColorType = (SkColorType)buffer.read32(); |
| + |
| + fRB = buffer.read32(); |
| + size_t size = this->computeMinSize(); |
| + fStorage = sk_malloc_throw(size); |
| + buffer.readByteArray(fStorage, size); |
| if (buffer.readBool()) { |
| fCTable = SkNEW_ARGS(SkColorTable, (buffer)); |
| } else { |
| fCTable = NULL; |
| } |
| - fOwnPixels = true; |
| - this->setPreLocked(fStorage, fCTable); |
| + this->setPreLocked(fStorage, fRB, fCTable); |
| } |