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 "SkMallocPixelRef.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.fWidth < 0 || info.fHeight < 0) {
     22             return false;
     23         }
     24         if (info.fWidth > maxDimension || info.fHeight > maxDimension) {
     25             return false;
     26         }
     27         if ((unsigned)info.fColorType > (unsigned)kLastEnum_SkColorType) {
     28             return false;
     29         }
     30         if ((unsigned)info.fAlphaType > (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.fHeight * 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*) SK_OVERRIDE;
     57     virtual void onDrawRectToRect(SkCanvas*, const SkRect*, const SkRect&, const SkPaint*) SK_OVERRIDE;
     58     virtual bool onReadPixels(SkBitmap*, const SkIRect&) const SK_OVERRIDE;
     59     virtual const void* onPeekPixels(SkImageInfo*, size_t* /*rowBytes*/) const SK_OVERRIDE;
     60     virtual bool getROPixels(SkBitmap*) const SK_OVERRIDE;
     61 
     62     // exposed for SkSurface_Raster via SkNewImageFromPixelRef
     63     SkImage_Raster(const SkImageInfo&, SkPixelRef*, size_t rowBytes);
     64 
     65     SkPixelRef* getPixelRef() const { return fBitmap.pixelRef(); }
     66 
     67 private:
     68     SkImage_Raster() : INHERITED(0, 0) {}
     69 
     70     SkBitmap    fBitmap;
     71 
     72     typedef SkImage_Base INHERITED;
     73 };
     74 
     75 ///////////////////////////////////////////////////////////////////////////////
     76 
     77 SkImage* SkImage_Raster::NewEmpty() {
     78     // Returns lazily created singleton
     79     static SkImage* gEmpty;
     80     if (NULL == gEmpty) {
     81         gEmpty = SkNEW(SkImage_Raster);
     82     }
     83     gEmpty->ref();
     84     return gEmpty;
     85 }
     86 
     87 static void release_data(void* addr, void* context) {
     88     SkData* data = static_cast<SkData*>(context);
     89     data->unref();
     90 }
     91 
     92 SkImage_Raster::SkImage_Raster(const Info& info, SkData* data, size_t rowBytes)
     93     : INHERITED(info.fWidth, info.fHeight)
     94 {
     95     data->ref();
     96     void* addr = const_cast<void*>(data->data());
     97     SkColorTable* ctable = NULL;
     98 
     99     fBitmap.installPixels(info, addr, rowBytes, ctable, release_data, data);
    100     fBitmap.setImmutable();
    101     fBitmap.lockPixels();
    102 }
    103 
    104 SkImage_Raster::SkImage_Raster(const Info& info, SkPixelRef* pr, size_t rowBytes)
    105     : INHERITED(info.fWidth, info.fHeight)
    106 {
    107     fBitmap.setInfo(info, rowBytes);
    108     fBitmap.setPixelRef(pr);
    109     fBitmap.lockPixels();
    110 }
    111 
    112 SkImage_Raster::~SkImage_Raster() {}
    113 
    114 void SkImage_Raster::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint) {
    115     canvas->drawBitmap(fBitmap, x, y, paint);
    116 }
    117 
    118 void SkImage_Raster::onDrawRectToRect(SkCanvas* canvas, const SkRect* src,
    119                                       const SkRect& dst, const SkPaint* paint) {
    120     canvas->drawBitmapRectToRect(fBitmap, src, dst, paint);
    121 }
    122 
    123 bool SkImage_Raster::onReadPixels(SkBitmap* dst, const SkIRect& subset) const {
    124     if (dst->pixelRef()) {
    125         return this->INHERITED::onReadPixels(dst, subset);
    126     } else {
    127         SkBitmap src;
    128         if (!fBitmap.extractSubset(&src, subset)) {
    129             return false;
    130         }
    131         return src.copyTo(dst, src.colorType());
    132     }
    133 }
    134 
    135 const void* SkImage_Raster::onPeekPixels(SkImageInfo* infoPtr,
    136                                          size_t* rowBytesPtr) const {
    137     const SkImageInfo info = fBitmap.info();
    138     if ((kUnknown_SkColorType == info.colorType()) || !fBitmap.getPixels()) {
    139         return NULL;
    140     }
    141     *infoPtr = info;
    142     *rowBytesPtr = fBitmap.rowBytes();
    143     return fBitmap.getPixels();
    144 }
    145 
    146 bool SkImage_Raster::getROPixels(SkBitmap* dst) const {
    147     *dst = fBitmap;
    148     return true;
    149 }
    150 
    151 ///////////////////////////////////////////////////////////////////////////////
    152 
    153 SkImage* SkImage::NewRasterCopy(const SkImageInfo& info, const void* pixels, size_t rowBytes) {
    154     if (!SkImage_Raster::ValidArgs(info, rowBytes)) {
    155         return NULL;
    156     }
    157     if (0 == info.fWidth && 0 == info.fHeight) {
    158         return SkImage_Raster::NewEmpty();
    159     }
    160     // check this after empty-check
    161     if (NULL == pixels) {
    162         return NULL;
    163     }
    164 
    165     // Here we actually make a copy of the caller's pixel data
    166     SkAutoDataUnref data(SkData::NewWithCopy(pixels, info.fHeight * rowBytes));
    167     return SkNEW_ARGS(SkImage_Raster, (info, data, rowBytes));
    168 }
    169 
    170 
    171 SkImage* SkImage::NewRasterData(const SkImageInfo& info, SkData* data, size_t rowBytes) {
    172     if (!SkImage_Raster::ValidArgs(info, rowBytes)) {
    173         return NULL;
    174     }
    175     if (0 == info.fWidth && 0 == info.fHeight) {
    176         return SkImage_Raster::NewEmpty();
    177     }
    178     // check this after empty-check
    179     if (NULL == data) {
    180         return NULL;
    181     }
    182 
    183     // did they give us enough data?
    184     size_t size = info.fHeight * rowBytes;
    185     if (data->size() < size) {
    186         return NULL;
    187     }
    188 
    189     return SkNEW_ARGS(SkImage_Raster, (info, data, rowBytes));
    190 }
    191 
    192 SkImage* SkNewImageFromPixelRef(const SkImageInfo& info, SkPixelRef* pr,
    193                                 size_t rowBytes) {
    194     return SkNEW_ARGS(SkImage_Raster, (info, pr, rowBytes));
    195 }
    196 
    197 SkPixelRef* SkBitmapImageGetPixelRef(SkImage* image) {
    198     return ((SkImage_Raster*)image)->getPixelRef();
    199 }
    200