Chromium Code Reviews| Index: src/image/SkImage_Raster.cpp |
| diff --git a/src/image/SkImage_Raster.cpp b/src/image/SkImage_Raster.cpp |
| index e4768af0ac17865da8e8bbd22881e57a6660439e..c55680e0ed471ffda561f62af9b0e96a2d06ce25 100644 |
| --- a/src/image/SkImage_Raster.cpp |
| +++ b/src/image/SkImage_Raster.cpp |
| @@ -10,47 +10,14 @@ |
| #include "SkBitmap.h" |
| #include "SkCanvas.h" |
| #include "SkData.h" |
| +#include "SkDecodingImageGenerator.h" |
| #include "SkMallocPixelRef.h" |
| +namespace { |
| class SkImage_Raster : public SkImage_Base { |
| public: |
| - static bool ValidArgs(const Info& info, size_t rowBytes) { |
| - const int maxDimension = SK_MaxS32 >> 2; |
| - const size_t kMaxPixelByteSize = SK_MaxS32; |
| - |
| - if (info.fWidth < 0 || info.fHeight < 0) { |
| - return false; |
| - } |
| - if (info.fWidth > maxDimension || info.fHeight > maxDimension) { |
| - return false; |
| - } |
| - if ((unsigned)info.fColorType > (unsigned)kLastEnum_SkColorType) { |
| - return false; |
| - } |
| - if ((unsigned)info.fAlphaType > (unsigned)kLastEnum_SkAlphaType) { |
| - return false; |
| - } |
| - |
| - if (kUnknown_SkColorType == info.colorType()) { |
| - return false; |
| - } |
| - |
| - // TODO: check colorspace |
| - |
| - if (rowBytes < SkImageMinRowBytes(info)) { |
| - return false; |
| - } |
| - |
| - int64_t size = (int64_t)info.fHeight * rowBytes; |
| - if (size > (int64_t)kMaxPixelByteSize) { |
| - return false; |
| - } |
| - return true; |
| - } |
| - |
| static SkImage* NewEmpty(); |
| - SkImage_Raster(const SkImageInfo&, SkData*, size_t rb); |
| virtual ~SkImage_Raster(); |
| virtual void onDraw(SkCanvas*, SkScalar, SkScalar, const SkPaint*) const SK_OVERRIDE; |
| @@ -60,17 +27,17 @@ public: |
| virtual const void* onPeekPixels(SkImageInfo*, size_t* /*rowBytes*/) const SK_OVERRIDE; |
| virtual bool getROPixels(SkBitmap*) const SK_OVERRIDE; |
| - // exposed for SkSurface_Raster via SkNewImageFromPixelRef |
| - SkImage_Raster(const SkImageInfo&, SkPixelRef*, size_t rowBytes); |
| - |
| - SkPixelRef* getPixelRef() const { return fBitmap.pixelRef(); } |
| - |
| virtual SkShader* onNewShader(SkShader::TileMode, |
| SkShader::TileMode, |
| const SkMatrix* localMatrix) const SK_OVERRIDE; |
| -private: |
| - SkImage_Raster() : INHERITED(0, 0) {} |
| + SkImage_Raster(const SkBitmap& bitmap) |
| + : INHERITED(bitmap.width(), bitmap.height()) |
| + , fBitmap(bitmap) { |
| + if (fBitmap.pixelRef() && fBitmap.pixelRef()->isLocked()) { |
| + fBitmap.lockPixels(); |
| + } |
| + } |
| SkBitmap fBitmap; |
| @@ -79,39 +46,53 @@ private: |
| /////////////////////////////////////////////////////////////////////////////// |
| +static bool valid_args(const SkImageInfo& info, size_t rowBytes) { |
| + const int maxDimension = SK_MaxS32 >> 2; |
| + const size_t kMaxPixelByteSize = SK_MaxS32; |
| + |
| + if (info.fWidth < 0 || info.fHeight < 0) { |
| + return false; |
| + } |
| + if (info.fWidth > maxDimension || info.fHeight > maxDimension) { |
| + return false; |
| + } |
| + if ((unsigned)info.fColorType > (unsigned)kLastEnum_SkColorType) { |
| + return false; |
| + } |
| + if ((unsigned)info.fAlphaType > (unsigned)kLastEnum_SkAlphaType) { |
| + return false; |
| + } |
| + |
| + if (kUnknown_SkColorType == info.colorType()) { |
| + return false; |
| + } |
| + |
| + // TODO: check colorspace |
| + |
| + if (rowBytes < SkImageMinRowBytes(info)) { |
| + return false; |
| + } |
| + |
| + int64_t size = (int64_t)info.fHeight * rowBytes; |
| + if (size > (int64_t)kMaxPixelByteSize) { |
| + return false; |
| + } |
| + return true; |
| +} |
| + |
| SkImage* SkImage_Raster::NewEmpty() { |
| // Returns lazily created singleton |
| static SkImage* gEmpty; |
| if (NULL == gEmpty) { |
| - gEmpty = SkNEW(SkImage_Raster); |
| + SkBitmap emptyBitmap; |
| + emptyBitmap.setImmutable(); |
| + gEmpty = SkNEW_ARGS(SkImage_Raster, (emptyBitmap)); |
| } |
| - gEmpty->ref(); |
| - return gEmpty; |
| -} |
| - |
| -static void release_data(void* addr, void* context) { |
| - SkData* data = static_cast<SkData*>(context); |
| - data->unref(); |
| -} |
| - |
| -SkImage_Raster::SkImage_Raster(const Info& info, SkData* data, size_t rowBytes) |
| - : INHERITED(info.fWidth, info.fHeight) |
| -{ |
| - data->ref(); |
| - void* addr = const_cast<void*>(data->data()); |
| - SkColorTable* ctable = NULL; |
| - |
| - fBitmap.installPixels(info, addr, rowBytes, ctable, release_data, data); |
| - fBitmap.setImmutable(); |
| - fBitmap.lockPixels(); |
| + return SkRef(gEmpty); |
| } |
| -SkImage_Raster::SkImage_Raster(const Info& info, SkPixelRef* pr, size_t rowBytes) |
| - : INHERITED(info.fWidth, info.fHeight) |
| -{ |
| - fBitmap.setInfo(info, rowBytes); |
| - fBitmap.setPixelRef(pr); |
| - fBitmap.lockPixels(); |
| +static void release_data(void*, void* context) { |
| + static_cast<SkData*>(context)->unref(); |
| } |
| SkImage_Raster::~SkImage_Raster() {} |
| @@ -156,11 +137,12 @@ bool SkImage_Raster::getROPixels(SkBitmap* dst) const { |
| *dst = fBitmap; |
| return true; |
| } |
| +} // namespace |
| /////////////////////////////////////////////////////////////////////////////// |
| SkImage* SkImage::NewRasterCopy(const SkImageInfo& info, const void* pixels, size_t rowBytes) { |
| - if (!SkImage_Raster::ValidArgs(info, rowBytes)) { |
| + if (!valid_args(info, rowBytes)) { |
| return NULL; |
| } |
| if (0 == info.fWidth && 0 == info.fHeight) { |
| @@ -173,12 +155,19 @@ SkImage* SkImage::NewRasterCopy(const SkImageInfo& info, const void* pixels, siz |
| // Here we actually make a copy of the caller's pixel data |
| SkAutoDataUnref data(SkData::NewWithCopy(pixels, info.fHeight * rowBytes)); |
| - return SkNEW_ARGS(SkImage_Raster, (info, data, rowBytes)); |
| + SkASSERT(data.get()); |
|
reed1
2014/08/11 21:14:08
assert not needed, we will crash if NewWithCopy fa
|
| + void* addr = const_cast<void*>(data->data()); |
| + SkColorTable* ctable = NULL; |
| + SkBitmap bitmap; |
| + bitmap.installPixels(info, addr, rowBytes, ctable, |
| + release_data, data.detach()); |
| + bitmap.setImmutable(); |
| + return SkNEW_ARGS(SkImage_Raster, (bitmap)); |
| } |
| SkImage* SkImage::NewRasterData(const SkImageInfo& info, SkData* data, size_t rowBytes) { |
| - if (!SkImage_Raster::ValidArgs(info, rowBytes)) { |
| + if (!valid_args(info, rowBytes)) { |
| return NULL; |
| } |
| if (0 == info.fWidth && 0 == info.fHeight) { |
| @@ -195,14 +184,38 @@ SkImage* SkImage::NewRasterData(const SkImageInfo& info, SkData* data, size_t ro |
| return NULL; |
| } |
| - return SkNEW_ARGS(SkImage_Raster, (info, data, rowBytes)); |
| + void* addr = const_cast<void*>(data->data()); |
| + SkColorTable* ctable = NULL; |
| + SkBitmap bitmap; |
| + bitmap.installPixels(info, addr, rowBytes, ctable, release_data, SkRef(data)); |
| + bitmap.setImmutable(); |
| + return SkNEW_ARGS(SkImage_Raster, (bitmap)); |
| } |
| SkImage* SkNewImageFromPixelRef(const SkImageInfo& info, SkPixelRef* pr, |
| size_t rowBytes) { |
| - return SkNEW_ARGS(SkImage_Raster, (info, pr, rowBytes)); |
| + SkBitmap bitmap; |
| + bitmap.setInfo(info, rowBytes); |
| + bitmap.setPixelRef(pr); |
| + return SkNEW_ARGS(SkImage_Raster, (bitmap)); |
| } |
| SkPixelRef* SkBitmapImageGetPixelRef(SkImage* image) { |
| - return ((SkImage_Raster*)image)->getPixelRef(); |
| + return ((SkImage_Raster*)image)->fBitmap.pixelRef(); |
| } |
| + |
| +SkImage* SkImage::NewEncodedData(SkData* data) { |
| + if (NULL == data) { |
| + return NULL; |
| + } |
| + SkBitmap bitmap; |
| + if (!SkInstallDiscardablePixelRef( |
| + SkDecodingImageGenerator::Create( |
| + data, SkDecodingImageGenerator::Options()), |
| + &bitmap)) { |
| + return NULL; |
| + } |
| + return SkNEW_ARGS(SkImage_Raster, (bitmap)); |
| +} |
| + |
| + |