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 "SkBitmap.h" 10 #include "SkCanvas.h" 11 #include "SkData.h" 12 #include "SkImageGenerator.h" 13 #include "SkImagePriv.h" 14 #include "SkPixelRef.h" 15 #include "SkSurface.h" 16 17 class SkImage_Raster : public SkImage_Base { 18 public: 19 static bool ValidArgs(const Info& info, size_t rowBytes) { 20 const int maxDimension = SK_MaxS32 >> 2; 21 const size_t kMaxPixelByteSize = SK_MaxS32; 22 23 if (info.width() <= 0 || info.height() <= 0) { 24 return false; 25 } 26 if (info.width() > maxDimension || info.height() > maxDimension) { 27 return false; 28 } 29 if ((unsigned)info.colorType() > (unsigned)kLastEnum_SkColorType) { 30 return false; 31 } 32 if ((unsigned)info.alphaType() > (unsigned)kLastEnum_SkAlphaType) { 33 return false; 34 } 35 36 if (kUnknown_SkColorType == info.colorType()) { 37 return false; 38 } 39 40 // TODO: check colorspace 41 42 if (rowBytes < SkImageMinRowBytes(info)) { 43 return false; 44 } 45 46 int64_t size = (int64_t)info.height() * rowBytes; 47 if (size > (int64_t)kMaxPixelByteSize) { 48 return false; 49 } 50 return true; 51 } 52 53 SkImage_Raster(const SkImageInfo&, SkData*, size_t rb, const SkSurfaceProps*); 54 virtual ~SkImage_Raster(); 55 56 SkSurface* onNewSurface(const SkImageInfo&, const SkSurfaceProps&) const override; 57 bool onReadPixels(const SkImageInfo&, void*, size_t, int srcX, int srcY) const override; 58 const void* onPeekPixels(SkImageInfo*, size_t* /*rowBytes*/) const override; 59 bool getROPixels(SkBitmap*) const override; 60 61 // exposed for SkSurface_Raster via SkNewImageFromPixelRef 62 SkImage_Raster(const SkImageInfo&, SkPixelRef*, const SkIPoint& pixelRefOrigin, size_t rowBytes, 63 const SkSurfaceProps*); 64 65 SkPixelRef* getPixelRef() const { return fBitmap.pixelRef(); } 66 67 SkShader* onNewShader(SkShader::TileMode, 68 SkShader::TileMode, 69 const SkMatrix* localMatrix) const override; 70 71 bool isOpaque() const override; 72 73 SkImage_Raster(const SkBitmap& bm, const SkSurfaceProps* props) 74 : INHERITED(bm.width(), bm.height(), props) 75 , fBitmap(bm) {} 76 77 private: 78 SkImage_Raster() : INHERITED(0, 0, NULL) {} 79 80 SkBitmap fBitmap; 81 82 typedef SkImage_Base INHERITED; 83 }; 84 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 const SkSurfaceProps* props) 94 : INHERITED(info.width(), info.height(), props) 95 { 96 data->ref(); 97 void* addr = const_cast<void*>(data->data()); 98 SkColorTable* ctable = NULL; 99 100 fBitmap.installPixels(info, addr, rowBytes, ctable, release_data, data); 101 fBitmap.setImmutable(); 102 fBitmap.lockPixels(); 103 } 104 105 SkImage_Raster::SkImage_Raster(const Info& info, SkPixelRef* pr, const SkIPoint& pixelRefOrigin, 106 size_t rowBytes, const SkSurfaceProps* props) 107 : INHERITED(info.width(), info.height(), props) 108 { 109 fBitmap.setInfo(info, rowBytes); 110 fBitmap.setPixelRef(pr, pixelRefOrigin); 111 fBitmap.lockPixels(); 112 } 113 114 SkImage_Raster::~SkImage_Raster() {} 115 116 SkShader* SkImage_Raster::onNewShader(SkShader::TileMode tileX, SkShader::TileMode tileY, 117 const SkMatrix* localMatrix) const { 118 return SkShader::CreateBitmapShader(fBitmap, tileX, tileY, localMatrix); 119 } 120 121 SkSurface* SkImage_Raster::onNewSurface(const SkImageInfo& info, const SkSurfaceProps& props) const { 122 return SkSurface::NewRaster(info, &props); 123 } 124 125 bool SkImage_Raster::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes, 126 int srcX, int srcY) const { 127 SkBitmap shallowCopy(fBitmap); 128 return shallowCopy.readPixels(dstInfo, dstPixels, dstRowBytes, srcX, srcY); 129 } 130 131 const void* SkImage_Raster::onPeekPixels(SkImageInfo* infoPtr, size_t* rowBytesPtr) const { 132 const SkImageInfo info = fBitmap.info(); 133 if ((kUnknown_SkColorType == info.colorType()) || !fBitmap.getPixels()) { 134 return NULL; 135 } 136 *infoPtr = info; 137 *rowBytesPtr = fBitmap.rowBytes(); 138 return fBitmap.getPixels(); 139 } 140 141 bool SkImage_Raster::getROPixels(SkBitmap* dst) const { 142 *dst = fBitmap; 143 return true; 144 } 145 146 /////////////////////////////////////////////////////////////////////////////// 147 148 SkImage* SkImage::NewRasterCopy(const SkImageInfo& info, const void* pixels, size_t rowBytes) { 149 if (!SkImage_Raster::ValidArgs(info, rowBytes) || !pixels) { 150 return NULL; 151 } 152 153 // Here we actually make a copy of the caller's pixel data 154 SkAutoDataUnref data(SkData::NewWithCopy(pixels, info.height() * rowBytes)); 155 return SkNEW_ARGS(SkImage_Raster, (info, data, rowBytes, NULL)); 156 } 157 158 159 SkImage* SkImage::NewRasterData(const SkImageInfo& info, SkData* data, size_t rowBytes) { 160 if (!SkImage_Raster::ValidArgs(info, rowBytes) || !data) { 161 return NULL; 162 } 163 164 // did they give us enough data? 165 size_t size = info.height() * rowBytes; 166 if (data->size() < size) { 167 return NULL; 168 } 169 170 return SkNEW_ARGS(SkImage_Raster, (info, data, rowBytes, NULL)); 171 } 172 173 SkImage* SkImage::NewFromGenerator(SkImageGenerator* generator) { 174 SkBitmap bitmap; 175 if (!SkInstallDiscardablePixelRef(generator, &bitmap)) { 176 return NULL; 177 } 178 if (0 == bitmap.width() || 0 == bitmap.height()) { 179 return NULL; 180 } 181 182 return SkNEW_ARGS(SkImage_Raster, (bitmap, NULL)); 183 } 184 185 SkImage* SkNewImageFromPixelRef(const SkImageInfo& info, SkPixelRef* pr, 186 const SkIPoint& pixelRefOrigin, size_t rowBytes, 187 const SkSurfaceProps* props) { 188 if (!SkImage_Raster::ValidArgs(info, rowBytes)) { 189 return NULL; 190 } 191 return SkNEW_ARGS(SkImage_Raster, (info, pr, pixelRefOrigin, rowBytes, props)); 192 } 193 194 SkImage* SkNewImageFromBitmap(const SkBitmap& bm, bool canSharePixelRef, 195 const SkSurfaceProps* props) { 196 if (!SkImage_Raster::ValidArgs(bm.info(), bm.rowBytes())) { 197 return NULL; 198 } 199 200 SkImage* image = NULL; 201 if (canSharePixelRef || bm.isImmutable()) { 202 image = SkNEW_ARGS(SkImage_Raster, (bm, props)); 203 } else { 204 bm.lockPixels(); 205 if (bm.getPixels()) { 206 image = SkImage::NewRasterCopy(bm.info(), bm.getPixels(), bm.rowBytes()); 207 } 208 bm.unlockPixels(); 209 210 // we don't expose props to NewRasterCopy (need a private vers) so post-init it here 211 if (image && props) { 212 as_IB(image)->initWithProps(*props); 213 } 214 } 215 return image; 216 } 217 218 const SkPixelRef* SkBitmapImageGetPixelRef(const SkImage* image) { 219 return ((const SkImage_Raster*)image)->getPixelRef(); 220 } 221 222 bool SkImage_Raster::isOpaque() const { 223 return fBitmap.isOpaque(); 224 } 225 226