gfx/skia/trunk/src/image/SkImage_Raster.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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  */
     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"
    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;
    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         }
    34         if (SkImageInfoToBitmapConfig(info) == SkBitmap::kNo_Config) {
    35             return false;
    36         }
    38         // TODO: check colorspace
    40         if (rowBytes < SkImageMinRowBytes(info)) {
    41             return false;
    42         }
    44         int64_t size = (int64_t)info.fHeight * rowBytes;
    45         if (size > (int64_t)kMaxPixelByteSize) {
    46             return false;
    47         }
    48         return true;
    49     }
    51     static SkImage* NewEmpty();
    53     SkImage_Raster(const SkImageInfo&, SkData*, size_t rb);
    54     virtual ~SkImage_Raster();
    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;
    62     // exposed for SkSurface_Raster via SkNewImageFromPixelRef
    63     SkImage_Raster(const SkImageInfo&, SkPixelRef*, size_t rowBytes);
    65     SkPixelRef* getPixelRef() const { return fBitmap.pixelRef(); }
    67 private:
    68     SkImage_Raster() : INHERITED(0, 0) {}
    70     SkBitmap    fBitmap;
    72     typedef SkImage_Base INHERITED;
    73 };
    75 ///////////////////////////////////////////////////////////////////////////////
    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 }
    87 static void release_data(void* addr, void* context) {
    88     SkData* data = static_cast<SkData*>(context);
    89     data->unref();
    90 }
    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());
    98     fBitmap.installPixels(info, addr, rowBytes, release_data, data);
    99     fBitmap.setImmutable();
   100     fBitmap.lockPixels();
   101 }
   103 SkImage_Raster::SkImage_Raster(const Info& info, SkPixelRef* pr, size_t rowBytes)
   104     : INHERITED(info.fWidth, info.fHeight)
   105 {
   106     fBitmap.setConfig(info, rowBytes);
   107     fBitmap.setPixelRef(pr);
   108     fBitmap.lockPixels();
   109 }
   111 SkImage_Raster::~SkImage_Raster() {}
   113 void SkImage_Raster::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint) {
   114     canvas->drawBitmap(fBitmap, x, y, paint);
   115 }
   117 void SkImage_Raster::onDrawRectToRect(SkCanvas* canvas, const SkRect* src,
   118                                       const SkRect& dst, const SkPaint* paint) {
   119     canvas->drawBitmapRectToRect(fBitmap, src, dst, paint);
   120 }
   122 bool SkImage_Raster::onReadPixels(SkBitmap* dst, const SkIRect& subset) const {
   123     if (dst->pixelRef()) {
   124         return this->INHERITED::onReadPixels(dst, subset);
   125     } else {
   126         SkBitmap src;
   127         if (!fBitmap.extractSubset(&src, subset)) {
   128             return false;
   129         }
   130         return src.copyTo(dst, src.colorType());
   131     }
   132 }
   134 const void* SkImage_Raster::onPeekPixels(SkImageInfo* infoPtr,
   135                                          size_t* rowBytesPtr) const {
   136     SkImageInfo info;
   137     if (!fBitmap.asImageInfo(&info) || !fBitmap.getPixels()) {
   138         return NULL;
   139     }
   140     *infoPtr = info;
   141     *rowBytesPtr = fBitmap.rowBytes();
   142     return fBitmap.getPixels();
   143 }
   145 bool SkImage_Raster::getROPixels(SkBitmap* dst) const {
   146     *dst = fBitmap;
   147     return true;
   148 }
   150 ///////////////////////////////////////////////////////////////////////////////
   152 SkImage* SkImage::NewRasterCopy(const SkImageInfo& info, const void* pixels, size_t rowBytes) {
   153     if (!SkImage_Raster::ValidArgs(info, rowBytes)) {
   154         return NULL;
   155     }
   156     if (0 == info.fWidth && 0 == info.fHeight) {
   157         return SkImage_Raster::NewEmpty();
   158     }
   159     // check this after empty-check
   160     if (NULL == pixels) {
   161         return NULL;
   162     }
   164     // Here we actually make a copy of the caller's pixel data
   165     SkAutoDataUnref data(SkData::NewWithCopy(pixels, info.fHeight * rowBytes));
   166     return SkNEW_ARGS(SkImage_Raster, (info, data, rowBytes));
   167 }
   170 SkImage* SkImage::NewRasterData(const SkImageInfo& info, SkData* data, size_t rowBytes) {
   171     if (!SkImage_Raster::ValidArgs(info, rowBytes)) {
   172         return NULL;
   173     }
   174     if (0 == info.fWidth && 0 == info.fHeight) {
   175         return SkImage_Raster::NewEmpty();
   176     }
   177     // check this after empty-check
   178     if (NULL == data) {
   179         return NULL;
   180     }
   182     // did they give us enough data?
   183     size_t size = info.fHeight * rowBytes;
   184     if (data->size() < size) {
   185         return NULL;
   186     }
   188     return SkNEW_ARGS(SkImage_Raster, (info, data, rowBytes));
   189 }
   191 SkImage* SkNewImageFromPixelRef(const SkImageInfo& info, SkPixelRef* pr,
   192                                 size_t rowBytes) {
   193     return SkNEW_ARGS(SkImage_Raster, (info, pr, rowBytes));
   194 }
   196 SkPixelRef* SkBitmapImageGetPixelRef(SkImage* image) {
   197     return ((SkImage_Raster*)image)->getPixelRef();
   198 }

mercurial