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