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 "SkDataPixelRef.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 (SkImageInfoToBitmapConfig(info) == SkBitmap::kNo_Config) {
     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 getROPixels(SkBitmap*) const SK_OVERRIDE;
     59 
     60     // exposed for SkSurface_Raster via SkNewImageFromPixelRef
     61     SkImage_Raster(const SkImageInfo&, SkPixelRef*, size_t rowBytes);
     62 
     63     SkPixelRef* getPixelRef() const { return fBitmap.pixelRef(); }
     64 
     65 private:
     66     SkImage_Raster() : INHERITED(0, 0) {}
     67 
     68     SkBitmap    fBitmap;
     69 
     70     typedef SkImage_Base INHERITED;
     71 };
     72 
     73 ///////////////////////////////////////////////////////////////////////////////
     74 
     75 SkImage* SkImage_Raster::NewEmpty() {
     76     // Returns lazily created singleton
     77     static SkImage* gEmpty;
     78     if (NULL == gEmpty) {
     79         gEmpty = SkNEW(SkImage_Raster);
     80     }
     81     gEmpty->ref();
     82     return gEmpty;
     83 }
     84 
     85 SkImage_Raster::SkImage_Raster(const Info& info, SkData* data, size_t rowBytes)
     86         : INHERITED(info.fWidth, info.fHeight) {
     87     fBitmap.setConfig(info, rowBytes);
     88     fBitmap.setPixelRef(SkNEW_ARGS(SkDataPixelRef, (info, data)))->unref();
     89     fBitmap.setImmutable();
     90 }
     91 
     92 SkImage_Raster::SkImage_Raster(const Info& info, SkPixelRef* pr, size_t rowBytes)
     93 : INHERITED(info.fWidth, info.fHeight) {
     94     SkBitmap::Config config = SkImageInfoToBitmapConfig(info);
     95 
     96     fBitmap.setConfig(config, info.fWidth, info.fHeight, rowBytes, info.fAlphaType);
     97     fBitmap.setPixelRef(pr);
     98 }
     99 
    100 SkImage_Raster::~SkImage_Raster() {}
    101 
    102 void SkImage_Raster::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint) {
    103     canvas->drawBitmap(fBitmap, x, y, paint);
    104 }
    105 
    106 void SkImage_Raster::onDrawRectToRect(SkCanvas* canvas, const SkRect* src, const SkRect& dst, const SkPaint* paint) {
    107     canvas->drawBitmapRectToRect(fBitmap, src, dst, paint);
    108 }
    109 
    110 bool SkImage_Raster::getROPixels(SkBitmap* dst) const {
    111     *dst = fBitmap;
    112     return true;
    113 }
    114 
    115 ///////////////////////////////////////////////////////////////////////////////
    116 
    117 SkImage* SkImage::NewRasterCopy(const SkImageInfo& info, const void* pixels, size_t rowBytes) {
    118     if (!SkImage_Raster::ValidArgs(info, rowBytes)) {
    119         return NULL;
    120     }
    121     if (0 == info.fWidth && 0 == info.fHeight) {
    122         return SkImage_Raster::NewEmpty();
    123     }
    124     // check this after empty-check
    125     if (NULL == pixels) {
    126         return NULL;
    127     }
    128 
    129     // Here we actually make a copy of the caller's pixel data
    130     SkAutoDataUnref data(SkData::NewWithCopy(pixels, info.fHeight * rowBytes));
    131     return SkNEW_ARGS(SkImage_Raster, (info, data, rowBytes));
    132 }
    133 
    134 
    135 SkImage* SkImage::NewRasterData(const SkImageInfo& info, SkData* pixelData, size_t rowBytes) {
    136     if (!SkImage_Raster::ValidArgs(info, rowBytes)) {
    137         return NULL;
    138     }
    139     if (0 == info.fWidth && 0 == info.fHeight) {
    140         return SkImage_Raster::NewEmpty();
    141     }
    142     // check this after empty-check
    143     if (NULL == pixelData) {
    144         return NULL;
    145     }
    146 
    147     // did they give us enough data?
    148     size_t size = info.fHeight * rowBytes;
    149     if (pixelData->size() < size) {
    150         return NULL;
    151     }
    152 
    153     SkAutoDataUnref data(pixelData);
    154     return SkNEW_ARGS(SkImage_Raster, (info, data, rowBytes));
    155 }
    156 
    157 SkImage* SkNewImageFromPixelRef(const SkImageInfo& info, SkPixelRef* pr,
    158                                 size_t rowBytes) {
    159     return SkNEW_ARGS(SkImage_Raster, (info, pr, rowBytes));
    160 }
    161 
    162 SkPixelRef* SkBitmapImageGetPixelRef(SkImage* image) {
    163     return ((SkImage_Raster*)image)->getPixelRef();
    164 }
    165