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 #ifndef SkImage_DEFINED 9 #define SkImage_DEFINED 10 11 #include "SkFilterQuality.h" 12 #include "SkImageInfo.h" 13 #include "SkImageEncoder.h" 14 #include "SkRefCnt.h" 15 #include "SkScalar.h" 16 #include "SkShader.h" 17 18 class SkData; 19 class SkCanvas; 20 class SkImageGenerator; 21 class SkPaint; 22 class SkString; 23 class SkSurface; 24 class SkSurfaceProps; 25 class GrContext; 26 class GrTexture; 27 28 /** 29 * SkImage is an abstraction for drawing a rectagle of pixels, though the 30 * particular type of image could be actually storing its data on the GPU, or 31 * as drawing commands (picture or PDF or otherwise), ready to be played back 32 * into another canvas. 33 * 34 * The content of SkImage is always immutable, though the actual storage may 35 * change, if for example that image can be re-created via encoded data or 36 * other means. 37 * 38 * SkImage always has a non-zero dimensions. If there is a request to create a new image, either 39 * directly or via SkSurface, and either of the requested dimensions are zero, then NULL will be 40 * returned. 41 */ 42 class SK_API SkImage : public SkRefCnt { 43 public: 44 SK_DECLARE_INST_COUNT(SkImage) 45 46 typedef SkImageInfo Info; 47 48 static SkImage* NewRasterCopy(const Info&, const void* pixels, size_t rowBytes); 49 static SkImage* NewRasterData(const Info&, SkData* pixels, size_t rowBytes); 50 51 /** 52 * Construct a new SkImage based on the given ImageGenerator. 53 * This function will always take ownership of the passed 54 * ImageGenerator. Returns NULL on error. 55 */ 56 static SkImage* NewFromGenerator(SkImageGenerator*); 57 58 /** 59 * Construct a new SkImage based on the specified encoded data. Returns NULL on failure, 60 * which can mean that the format of the encoded data was not recognized/supported. 61 * 62 * Regardless of success or failure, the caller is responsible for managing their ownership 63 * of the data. 64 */ 65 static SkImage* NewFromData(SkData* data); 66 67 /** 68 * Create a new image from the specified descriptor. Note - the caller is responsible for 69 * managing the lifetime of the underlying platform texture. 70 * 71 * Will return NULL if the specified descriptor is unsupported. 72 */ 73 static SkImage* NewFromTexture(GrContext*, const GrBackendTextureDesc&, 74 SkAlphaType = kPremul_SkAlphaType); 75 76 /** 77 * Create a new image by copying the pixels from the specified descriptor. No reference is 78 * kept to the original platform texture. 79 * 80 * Will return NULL if the specified descriptor is unsupported. 81 */ 82 static SkImage* NewFromTextureCopy(GrContext*, const GrBackendTextureDesc&, 83 SkAlphaType = kPremul_SkAlphaType); 84 width()85 int width() const { return fWidth; } height()86 int height() const { return fHeight; } uniqueID()87 uint32_t uniqueID() const { return fUniqueID; } isOpaque()88 virtual bool isOpaque() const { return false; } 89 90 /** 91 * Return the GrTexture that stores the image pixels. Calling getTexture 92 * does not affect the reference count of the GrTexture object. 93 * Will return NULL if the image does not use a texture. 94 */ 95 GrTexture* getTexture() const; 96 97 virtual SkShader* newShader(SkShader::TileMode, 98 SkShader::TileMode, 99 const SkMatrix* localMatrix = NULL) const; 100 101 /** 102 * If the image has direct access to its pixels (i.e. they are in local 103 * RAM) return the (const) address of those pixels, and if not null, return 104 * the ImageInfo and rowBytes. The returned address is only valid while 105 * the image object is in scope. 106 * 107 * On failure, returns NULL and the info and rowBytes parameters are 108 * ignored. 109 */ 110 const void* peekPixels(SkImageInfo* info, size_t* rowBytes) const; 111 112 /** 113 * Copy the pixels from the image into the specified buffer (pixels + rowBytes), 114 * converting them into the requested format (dstInfo). The image pixels are read 115 * starting at the specified (srcX,srcY) location. 116 * 117 * The specified ImageInfo and (srcX,srcY) offset specifies a source rectangle 118 * 119 * srcR.setXYWH(srcX, srcY, dstInfo.width(), dstInfo.height()); 120 * 121 * srcR is intersected with the bounds of the image. If this intersection is not empty, 122 * then we have two sets of pixels (of equal size). Replace the dst pixels with the 123 * corresponding src pixels, performing any colortype/alphatype transformations needed 124 * (in the case where the src and dst have different colortypes or alphatypes). 125 * 126 * This call can fail, returning false, for several reasons: 127 * - If srcR does not intersect the image bounds. 128 * - If the requested colortype/alphatype cannot be converted from the image's types. 129 */ 130 bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes, 131 int srcX, int srcY) const; 132 133 /** 134 * Encode the image's pixels and return the result as a new SkData, which 135 * the caller must manage (i.e. call unref() when they are done). 136 * 137 * If the image type cannot be encoded, or the requested encoder type is 138 * not supported, this will return NULL. 139 */ 140 SkData* encode(SkImageEncoder::Type t = SkImageEncoder::kPNG_Type, 141 int quality = 80) const; 142 143 /** 144 * Return a new surface that is compatible with this image's internal representation 145 * (e.g. raster or gpu). 146 * 147 * If no surfaceprops are specified, the image will attempt to match the props of when it 148 * was created (if it came from a surface). 149 */ 150 SkSurface* newSurface(const SkImageInfo&, const SkSurfaceProps* = NULL) const; 151 152 const char* toString(SkString*) const; 153 154 /** 155 * Return an image that is a rescale of this image (using newWidth, newHeight). 156 * 157 * If subset is NULL, then the entire original image is used as the src for the scaling. 158 * If subset is not NULL, then it specifies subset of src-pixels used for scaling. If 159 * subset extends beyond the bounds of the original image, then NULL is returned. 160 * 161 * Notes: 162 * - newWidth and newHeight must be > 0 or NULL will be returned. 163 * 164 * - it is legal for the returned image to be the same instance as the src image 165 * (if the new dimensions == the src dimensions and subset is NULL or == src dimensions). 166 * 167 * - it is legal for the "scaled" image to have changed its SkAlphaType from unpremul 168 * to premul (as required by the impl). The image should draw (nearly) identically, 169 * since during drawing we will "apply the alpha" to the pixels. Future optimizations 170 * may take away this caveat, preserving unpremul. 171 */ 172 SkImage* newImage(int newWidth, int newHeight, const SkIRect* subset = NULL, 173 SkFilterQuality = kNone_SkFilterQuality) const; 174 175 protected: SkImage(int width,int height)176 SkImage(int width, int height) : 177 fWidth(width), 178 fHeight(height), 179 fUniqueID(NextUniqueID()) { 180 181 SkASSERT(width > 0); 182 SkASSERT(height > 0); 183 } 184 185 private: 186 const int fWidth; 187 const int fHeight; 188 const uint32_t fUniqueID; 189 190 static uint32_t NextUniqueID(); 191 192 typedef SkRefCnt INHERITED; 193 }; 194 195 #endif 196