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 59 // exposed for SkSurface_Raster via SkNewImageFromPixelRef 60 SkImage_Raster(const SkImage::Info&, SkPixelRef*, size_t rowBytes); 61 62 SkPixelRef* getPixelRef() const { return fBitmap.pixelRef(); } 63 64 private: 65 SkImage_Raster() : INHERITED(0, 0) {} 66 67 SkBitmap fBitmap; 68 69 typedef SkImage_Base INHERITED; 70 }; 71 72 /////////////////////////////////////////////////////////////////////////////// 73 74 SkImage* SkImage_Raster::NewEmpty() { 75 // Returns lazily created singleton 76 static SkImage* gEmpty; 77 if (NULL == gEmpty) { 78 gEmpty = SkNEW(SkImage_Raster); 79 } 80 gEmpty->ref(); 81 return gEmpty; 82 } 83 84 SkImage_Raster::SkImage_Raster(const Info& info, SkData* data, size_t rowBytes) 85 : INHERITED(info.fWidth, info.fHeight) { 86 bool isOpaque; 87 SkBitmap::Config config = SkImageInfoToBitmapConfig(info, &isOpaque); 88 89 fBitmap.setConfig(config, info.fWidth, info.fHeight, rowBytes); 90 fBitmap.setPixelRef(SkNEW_ARGS(SkDataPixelRef, (data)))->unref(); 91 fBitmap.setIsOpaque(isOpaque); 92 fBitmap.setImmutable(); 93 } 94 95 SkImage_Raster::SkImage_Raster(const Info& info, SkPixelRef* pr, size_t rowBytes) 96 : INHERITED(info.fWidth, info.fHeight) { 97 bool isOpaque; 98 SkBitmap::Config config = SkImageInfoToBitmapConfig(info, &isOpaque); 99 100 fBitmap.setConfig(config, info.fWidth, info.fHeight, rowBytes); 101 fBitmap.setPixelRef(pr); 102 fBitmap.setIsOpaque(isOpaque); 103 fBitmap.setImmutable(); 104 } 105 106 SkImage_Raster::~SkImage_Raster() {} 107 108 void SkImage_Raster::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint) { 109 canvas->drawBitmap(fBitmap, x, y, paint); 110 } 111 112 /////////////////////////////////////////////////////////////////////////////// 113 114 SkImage* SkImage::NewRasterCopy(const SkImage::Info& info, const void* pixels, size_t rowBytes) { 115 if (!SkImage_Raster::ValidArgs(info, rowBytes)) { 116 return NULL; 117 } 118 if (0 == info.fWidth && 0 == info.fHeight) { 119 return SkImage_Raster::NewEmpty(); 120 } 121 // check this after empty-check 122 if (NULL == pixels) { 123 return NULL; 124 } 125 126 // Here we actually make a copy of the caller's pixel data 127 SkAutoDataUnref data(SkData::NewWithCopy(pixels, info.fHeight * rowBytes)); 128 return SkNEW_ARGS(SkImage_Raster, (info, data, rowBytes)); 129 } 130 131 132 SkImage* SkImage::NewRasterData(const SkImage::Info& info, SkData* pixelData, size_t rowBytes) { 133 if (!SkImage_Raster::ValidArgs(info, rowBytes)) { 134 return NULL; 135 } 136 if (0 == info.fWidth && 0 == info.fHeight) { 137 return SkImage_Raster::NewEmpty(); 138 } 139 // check this after empty-check 140 if (NULL == pixelData) { 141 return NULL; 142 } 143 144 // did they give us enough data? 145 size_t size = info.fHeight * rowBytes; 146 if (pixelData->size() < size) { 147 return NULL; 148 } 149 150 SkAutoDataUnref data(pixelData); 151 return SkNEW_ARGS(SkImage_Raster, (info, data, rowBytes)); 152 } 153 154 SkImage* SkNewImageFromPixelRef(const SkImage::Info& info, SkPixelRef* pr, 155 size_t rowBytes) { 156 return SkNEW_ARGS(SkImage_Raster, (info, pr, rowBytes)); 157 } 158 159 SkPixelRef* SkBitmapImageGetPixelRef(SkImage* image) { 160 return ((SkImage_Raster*)image)->getPixelRef(); 161 } 162