Home | History | Annotate | Download | only in image
      1 /*
      2  * Copyright 2012 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #include "SkImage_Base.h"
      9 #include "SkImagePriv.h"
     10 #include "SkBitmap.h"
     11 #include "SkCanvas.h"
     12 #include "SkData.h"
     13 #include "SkDecodingImageGenerator.h"
     14 
     15 class SkImage_Raster : public SkImage_Base {
     16 public:
     17     static bool ValidArgs(const Info& info, size_t rowBytes) {
     18         const int maxDimension = SK_MaxS32 >> 2;
     19         const size_t kMaxPixelByteSize = SK_MaxS32;
     20 
     21         if (info.width() < 0 || info.height() < 0) {
     22             return false;
     23         }
     24         if (info.width() > maxDimension || info.height() > maxDimension) {
     25             return false;
     26         }
     27         if ((unsigned)info.colorType() > (unsigned)kLastEnum_SkColorType) {
     28             return false;
     29         }
     30         if ((unsigned)info.alphaType() > (unsigned)kLastEnum_SkAlphaType) {
     31             return false;
     32         }
     33 
     34         if (kUnknown_SkColorType == info.colorType()) {
     35             return false;
     36         }
     37 
     38         // TODO: check colorspace
     39 
     40         if (rowBytes < SkImageMinRowBytes(info)) {
     41             return false;
     42         }
     43 
     44         int64_t size = (int64_t)info.height() * rowBytes;
     45         if (size > (int64_t)kMaxPixelByteSize) {
     46             return false;
     47         }
     48         return true;
     49     }
     50 
     51     static SkImage* NewEmpty();
     52 
     53     SkImage_Raster(const SkImageInfo&, SkData*, size_t rb);
     54     virtual ~SkImage_Raster();
     55 
     56     virtual void onDraw(SkCanvas*, SkScalar, SkScalar, const SkPaint*) const SK_OVERRIDE;
     57     virtual void onDrawRectToRect(SkCanvas*, const SkRect*, const SkRect&,
     58                                   const SkPaint*) const SK_OVERRIDE;
     59     virtual bool onReadPixels(SkBitmap*, const SkIRect&) const SK_OVERRIDE;
     60     virtual const void* onPeekPixels(SkImageInfo*, size_t* /*rowBytes*/) const SK_OVERRIDE;
     61     virtual bool getROPixels(SkBitmap*) const SK_OVERRIDE;
     62 
     63     // exposed for SkSurface_Raster via SkNewImageFromPixelRef
     64     SkImage_Raster(const SkImageInfo&, SkPixelRef*, size_t rowBytes);
     65 
     66     SkPixelRef* getPixelRef() const { return fBitmap.pixelRef(); }
     67 
     68     virtual SkShader* onNewShader(SkShader::TileMode,
     69                                   SkShader::TileMode,
     70                                   const SkMatrix* localMatrix) const SK_OVERRIDE;
     71 
     72     virtual bool isOpaque() const SK_OVERRIDE;
     73 
     74     SkImage_Raster(const SkBitmap& bm)
     75         : INHERITED(bm.width(), bm.height())
     76         , fBitmap(bm) {}
     77 
     78 private:
     79     SkImage_Raster() : INHERITED(0, 0) {}
     80 
     81     SkBitmap    fBitmap;
     82 
     83     typedef SkImage_Base INHERITED;
     84 };
     85 
     86 ///////////////////////////////////////////////////////////////////////////////
     87 
     88 SkImage* SkImage_Raster::NewEmpty() {
     89     // Returns lazily created singleton
     90     static SkImage* gEmpty;
     91     if (NULL == gEmpty) {
     92         gEmpty = SkNEW(SkImage_Raster);
     93     }
     94     gEmpty->ref();
     95     return gEmpty;
     96 }
     97 
     98 static void release_data(void* addr, void* context) {
     99     SkData* data = static_cast<SkData*>(context);
    100     data->unref();
    101 }
    102 
    103 SkImage_Raster::SkImage_Raster(const Info& info, SkData* data, size_t rowBytes)
    104     : INHERITED(info.width(), info.height())
    105 {
    106     data->ref();
    107     void* addr = const_cast<void*>(data->data());
    108     SkColorTable* ctable = NULL;
    109 
    110     fBitmap.installPixels(info, addr, rowBytes, ctable, release_data, data);
    111     fBitmap.setImmutable();
    112     fBitmap.lockPixels();
    113 }
    114 
    115 SkImage_Raster::SkImage_Raster(const Info& info, SkPixelRef* pr, size_t rowBytes)
    116     : INHERITED(info.width(), info.height())
    117 {
    118     fBitmap.setInfo(info, rowBytes);
    119     fBitmap.setPixelRef(pr);
    120     fBitmap.lockPixels();
    121 }
    122 
    123 SkImage_Raster::~SkImage_Raster() {}
    124 
    125 SkShader* SkImage_Raster::onNewShader(SkShader::TileMode tileX, SkShader::TileMode tileY,
    126                                       const SkMatrix* localMatrix) const {
    127     return SkShader::CreateBitmapShader(fBitmap, tileX, tileY, localMatrix);
    128 }
    129 
    130 void SkImage_Raster::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint) const {
    131     canvas->drawBitmap(fBitmap, x, y, paint);
    132 }
    133 
    134 void SkImage_Raster::onDrawRectToRect(SkCanvas* canvas, const SkRect* src, const SkRect& dst,
    135                                       const SkPaint* paint) const {
    136     canvas->drawBitmapRectToRect(fBitmap, src, dst, paint);
    137 }
    138 
    139 bool SkImage_Raster::onReadPixels(SkBitmap* dst, const SkIRect& subset) const {
    140     if (dst->pixelRef()) {
    141         return this->INHERITED::onReadPixels(dst, subset);
    142     } else {
    143         SkBitmap src;
    144         if (!fBitmap.extractSubset(&src, subset)) {
    145             return false;
    146         }
    147         return src.copyTo(dst, src.colorType());
    148     }
    149 }
    150 
    151 const void* SkImage_Raster::onPeekPixels(SkImageInfo* infoPtr, size_t* rowBytesPtr) const {
    152     const SkImageInfo info = fBitmap.info();
    153     if ((kUnknown_SkColorType == info.colorType()) || !fBitmap.getPixels()) {
    154         return NULL;
    155     }
    156     *infoPtr = info;
    157     *rowBytesPtr = fBitmap.rowBytes();
    158     return fBitmap.getPixels();
    159 }
    160 
    161 bool SkImage_Raster::getROPixels(SkBitmap* dst) const {
    162     *dst = fBitmap;
    163     return true;
    164 }
    165 
    166 ///////////////////////////////////////////////////////////////////////////////
    167 
    168 SkImage* SkImage::NewRasterCopy(const SkImageInfo& info, const void* pixels, size_t rowBytes) {
    169     if (!SkImage_Raster::ValidArgs(info, rowBytes)) {
    170         return NULL;
    171     }
    172     if (0 == info.width() && 0 == info.height()) {
    173         return SkImage_Raster::NewEmpty();
    174     }
    175     // check this after empty-check
    176     if (NULL == pixels) {
    177         return NULL;
    178     }
    179 
    180     // Here we actually make a copy of the caller's pixel data
    181     SkAutoDataUnref data(SkData::NewWithCopy(pixels, info.height() * rowBytes));
    182     return SkNEW_ARGS(SkImage_Raster, (info, data, rowBytes));
    183 }
    184 
    185 
    186 SkImage* SkImage::NewRasterData(const SkImageInfo& info, SkData* data, size_t rowBytes) {
    187     if (!SkImage_Raster::ValidArgs(info, rowBytes)) {
    188         return NULL;
    189     }
    190     if (0 == info.width() && 0 == info.height()) {
    191         return SkImage_Raster::NewEmpty();
    192     }
    193     // check this after empty-check
    194     if (NULL == data) {
    195         return NULL;
    196     }
    197 
    198     // did they give us enough data?
    199     size_t size = info.height() * rowBytes;
    200     if (data->size() < size) {
    201         return NULL;
    202     }
    203 
    204     return SkNEW_ARGS(SkImage_Raster, (info, data, rowBytes));
    205 }
    206 
    207 SkImage* SkImage::NewFromGenerator(SkImageGenerator* generator) {
    208     SkBitmap bitmap;
    209     if (!SkInstallDiscardablePixelRef(generator, &bitmap)) {
    210         return NULL;
    211     }
    212     return SkNEW_ARGS(SkImage_Raster, (bitmap));
    213 }
    214 
    215 SkImage* SkNewImageFromPixelRef(const SkImageInfo& info, SkPixelRef* pr,
    216                                 size_t rowBytes) {
    217     return SkNEW_ARGS(SkImage_Raster, (info, pr, rowBytes));
    218 }
    219 
    220 SkPixelRef* SkBitmapImageGetPixelRef(SkImage* image) {
    221     return ((SkImage_Raster*)image)->getPixelRef();
    222 }
    223 
    224 bool SkImage_Raster::isOpaque() const {
    225     return fBitmap.isOpaque();
    226 }
    227