1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/image/SkImage_Raster.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,198 @@ 1.4 +/* 1.5 + * Copyright 2012 Google Inc. 1.6 + * 1.7 + * Use of this source code is governed by a BSD-style license that can be 1.8 + * found in the LICENSE file. 1.9 + */ 1.10 + 1.11 +#include "SkImage_Base.h" 1.12 +#include "SkImagePriv.h" 1.13 +#include "SkBitmap.h" 1.14 +#include "SkCanvas.h" 1.15 +#include "SkData.h" 1.16 +#include "SkMallocPixelRef.h" 1.17 + 1.18 +class SkImage_Raster : public SkImage_Base { 1.19 +public: 1.20 + static bool ValidArgs(const Info& info, size_t rowBytes) { 1.21 + const int maxDimension = SK_MaxS32 >> 2; 1.22 + const size_t kMaxPixelByteSize = SK_MaxS32; 1.23 + 1.24 + if (info.fWidth < 0 || info.fHeight < 0) { 1.25 + return false; 1.26 + } 1.27 + if (info.fWidth > maxDimension || info.fHeight > maxDimension) { 1.28 + return false; 1.29 + } 1.30 + if ((unsigned)info.fColorType > (unsigned)kLastEnum_SkColorType) { 1.31 + return false; 1.32 + } 1.33 + if ((unsigned)info.fAlphaType > (unsigned)kLastEnum_SkAlphaType) { 1.34 + return false; 1.35 + } 1.36 + 1.37 + if (SkImageInfoToBitmapConfig(info) == SkBitmap::kNo_Config) { 1.38 + return false; 1.39 + } 1.40 + 1.41 + // TODO: check colorspace 1.42 + 1.43 + if (rowBytes < SkImageMinRowBytes(info)) { 1.44 + return false; 1.45 + } 1.46 + 1.47 + int64_t size = (int64_t)info.fHeight * rowBytes; 1.48 + if (size > (int64_t)kMaxPixelByteSize) { 1.49 + return false; 1.50 + } 1.51 + return true; 1.52 + } 1.53 + 1.54 + static SkImage* NewEmpty(); 1.55 + 1.56 + SkImage_Raster(const SkImageInfo&, SkData*, size_t rb); 1.57 + virtual ~SkImage_Raster(); 1.58 + 1.59 + virtual void onDraw(SkCanvas*, SkScalar, SkScalar, const SkPaint*) SK_OVERRIDE; 1.60 + virtual void onDrawRectToRect(SkCanvas*, const SkRect*, const SkRect&, const SkPaint*) SK_OVERRIDE; 1.61 + virtual bool onReadPixels(SkBitmap*, const SkIRect&) const SK_OVERRIDE; 1.62 + virtual const void* onPeekPixels(SkImageInfo*, size_t* /*rowBytes*/) const SK_OVERRIDE; 1.63 + virtual bool getROPixels(SkBitmap*) const SK_OVERRIDE; 1.64 + 1.65 + // exposed for SkSurface_Raster via SkNewImageFromPixelRef 1.66 + SkImage_Raster(const SkImageInfo&, SkPixelRef*, size_t rowBytes); 1.67 + 1.68 + SkPixelRef* getPixelRef() const { return fBitmap.pixelRef(); } 1.69 + 1.70 +private: 1.71 + SkImage_Raster() : INHERITED(0, 0) {} 1.72 + 1.73 + SkBitmap fBitmap; 1.74 + 1.75 + typedef SkImage_Base INHERITED; 1.76 +}; 1.77 + 1.78 +/////////////////////////////////////////////////////////////////////////////// 1.79 + 1.80 +SkImage* SkImage_Raster::NewEmpty() { 1.81 + // Returns lazily created singleton 1.82 + static SkImage* gEmpty; 1.83 + if (NULL == gEmpty) { 1.84 + gEmpty = SkNEW(SkImage_Raster); 1.85 + } 1.86 + gEmpty->ref(); 1.87 + return gEmpty; 1.88 +} 1.89 + 1.90 +static void release_data(void* addr, void* context) { 1.91 + SkData* data = static_cast<SkData*>(context); 1.92 + data->unref(); 1.93 +} 1.94 + 1.95 +SkImage_Raster::SkImage_Raster(const Info& info, SkData* data, size_t rowBytes) 1.96 + : INHERITED(info.fWidth, info.fHeight) 1.97 +{ 1.98 + data->ref(); 1.99 + void* addr = const_cast<void*>(data->data()); 1.100 + 1.101 + fBitmap.installPixels(info, addr, rowBytes, release_data, data); 1.102 + fBitmap.setImmutable(); 1.103 + fBitmap.lockPixels(); 1.104 +} 1.105 + 1.106 +SkImage_Raster::SkImage_Raster(const Info& info, SkPixelRef* pr, size_t rowBytes) 1.107 + : INHERITED(info.fWidth, info.fHeight) 1.108 +{ 1.109 + fBitmap.setConfig(info, rowBytes); 1.110 + fBitmap.setPixelRef(pr); 1.111 + fBitmap.lockPixels(); 1.112 +} 1.113 + 1.114 +SkImage_Raster::~SkImage_Raster() {} 1.115 + 1.116 +void SkImage_Raster::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint) { 1.117 + canvas->drawBitmap(fBitmap, x, y, paint); 1.118 +} 1.119 + 1.120 +void SkImage_Raster::onDrawRectToRect(SkCanvas* canvas, const SkRect* src, 1.121 + const SkRect& dst, const SkPaint* paint) { 1.122 + canvas->drawBitmapRectToRect(fBitmap, src, dst, paint); 1.123 +} 1.124 + 1.125 +bool SkImage_Raster::onReadPixels(SkBitmap* dst, const SkIRect& subset) const { 1.126 + if (dst->pixelRef()) { 1.127 + return this->INHERITED::onReadPixels(dst, subset); 1.128 + } else { 1.129 + SkBitmap src; 1.130 + if (!fBitmap.extractSubset(&src, subset)) { 1.131 + return false; 1.132 + } 1.133 + return src.copyTo(dst, src.colorType()); 1.134 + } 1.135 +} 1.136 + 1.137 +const void* SkImage_Raster::onPeekPixels(SkImageInfo* infoPtr, 1.138 + size_t* rowBytesPtr) const { 1.139 + SkImageInfo info; 1.140 + if (!fBitmap.asImageInfo(&info) || !fBitmap.getPixels()) { 1.141 + return NULL; 1.142 + } 1.143 + *infoPtr = info; 1.144 + *rowBytesPtr = fBitmap.rowBytes(); 1.145 + return fBitmap.getPixels(); 1.146 +} 1.147 + 1.148 +bool SkImage_Raster::getROPixels(SkBitmap* dst) const { 1.149 + *dst = fBitmap; 1.150 + return true; 1.151 +} 1.152 + 1.153 +/////////////////////////////////////////////////////////////////////////////// 1.154 + 1.155 +SkImage* SkImage::NewRasterCopy(const SkImageInfo& info, const void* pixels, size_t rowBytes) { 1.156 + if (!SkImage_Raster::ValidArgs(info, rowBytes)) { 1.157 + return NULL; 1.158 + } 1.159 + if (0 == info.fWidth && 0 == info.fHeight) { 1.160 + return SkImage_Raster::NewEmpty(); 1.161 + } 1.162 + // check this after empty-check 1.163 + if (NULL == pixels) { 1.164 + return NULL; 1.165 + } 1.166 + 1.167 + // Here we actually make a copy of the caller's pixel data 1.168 + SkAutoDataUnref data(SkData::NewWithCopy(pixels, info.fHeight * rowBytes)); 1.169 + return SkNEW_ARGS(SkImage_Raster, (info, data, rowBytes)); 1.170 +} 1.171 + 1.172 + 1.173 +SkImage* SkImage::NewRasterData(const SkImageInfo& info, SkData* data, size_t rowBytes) { 1.174 + if (!SkImage_Raster::ValidArgs(info, rowBytes)) { 1.175 + return NULL; 1.176 + } 1.177 + if (0 == info.fWidth && 0 == info.fHeight) { 1.178 + return SkImage_Raster::NewEmpty(); 1.179 + } 1.180 + // check this after empty-check 1.181 + if (NULL == data) { 1.182 + return NULL; 1.183 + } 1.184 + 1.185 + // did they give us enough data? 1.186 + size_t size = info.fHeight * rowBytes; 1.187 + if (data->size() < size) { 1.188 + return NULL; 1.189 + } 1.190 + 1.191 + return SkNEW_ARGS(SkImage_Raster, (info, data, rowBytes)); 1.192 +} 1.193 + 1.194 +SkImage* SkNewImageFromPixelRef(const SkImageInfo& info, SkPixelRef* pr, 1.195 + size_t rowBytes) { 1.196 + return SkNEW_ARGS(SkImage_Raster, (info, pr, rowBytes)); 1.197 +} 1.198 + 1.199 +SkPixelRef* SkBitmapImageGetPixelRef(SkImage* image) { 1.200 + return ((SkImage_Raster*)image)->getPixelRef(); 1.201 +}