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