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