#include "SkImage_Base.h"
#include "SkBitmap.h"
#include "SkCanvas.h"
+#include "SkColorTable.h"
#include "SkData.h"
#include "SkImageGeneratorPriv.h"
#include "SkImagePriv.h"
class SkImage_Raster : public SkImage_Base {
public:
- static bool ValidArgs(const Info& info, size_t rowBytes, size_t* minSize) {
+ static bool ValidArgs(const Info& info, size_t rowBytes, SkColorTable* ctable,
+ size_t* minSize) {
const int maxDimension = SK_MaxS32 >> 2;
if (info.width() <= 0 || info.height() <= 0) {
return false;
}
- // TODO: check colorspace
+ const bool needsCT = kIndex_8_SkColorType == info.colorType();
+ const bool hasCT = NULL != ctable;
+ if (needsCT != hasCT) {
+ return false;
+ }
if (rowBytes < SkImageMinRowBytes(info)) {
return false;
return true;
}
- SkImage_Raster(const SkImageInfo&, SkData*, size_t rb, const SkSurfaceProps*);
+ SkImage_Raster(const SkImageInfo&, SkData*, size_t rb, SkColorTable*, const SkSurfaceProps*);
virtual ~SkImage_Raster();
SkSurface* onNewSurface(const SkImageInfo&, const SkSurfaceProps&) const override;
}
SkImage_Raster::SkImage_Raster(const Info& info, SkData* data, size_t rowBytes,
- const SkSurfaceProps* props)
+ SkColorTable* ctable, const SkSurfaceProps* props)
: INHERITED(info.width(), info.height(), props)
{
data->ref();
void* addr = const_cast<void*>(data->data());
- SkColorTable* ctable = NULL;
fBitmap.installPixels(info, addr, rowBytes, ctable, release_data, data);
fBitmap.setImmutable();
///////////////////////////////////////////////////////////////////////////////
-SkImage* SkImage::NewRasterCopy(const SkImageInfo& info, const void* pixels, size_t rowBytes) {
+SkImage* SkImage::NewRasterCopy(const SkImageInfo& info, const void* pixels, size_t rowBytes,
+ SkColorTable* ctable) {
size_t size;
- if (!SkImage_Raster::ValidArgs(info, rowBytes, &size) || !pixels) {
+ if (!SkImage_Raster::ValidArgs(info, rowBytes, ctable, &size) || !pixels) {
return NULL;
}
// Here we actually make a copy of the caller's pixel data
SkAutoDataUnref data(SkData::NewWithCopy(pixels, size));
- return SkNEW_ARGS(SkImage_Raster, (info, data, rowBytes, NULL));
+ return SkNEW_ARGS(SkImage_Raster, (info, data, rowBytes, ctable, NULL));
}
SkImage* SkImage::NewRasterData(const SkImageInfo& info, SkData* data, size_t rowBytes) {
size_t size;
- if (!SkImage_Raster::ValidArgs(info, rowBytes, &size) || !data) {
+ if (!SkImage_Raster::ValidArgs(info, rowBytes, NULL, &size) || !data) {
return NULL;
}
return NULL;
}
- return SkNEW_ARGS(SkImage_Raster, (info, data, rowBytes, NULL));
+ SkColorTable* ctable = NULL;
+ return SkNEW_ARGS(SkImage_Raster, (info, data, rowBytes, ctable, NULL));
}
SkImage* SkImage::NewFromRaster(const SkImageInfo& info, const void* pixels, size_t rowBytes,
RasterReleaseProc proc, ReleaseContext ctx) {
size_t size;
- if (!SkImage_Raster::ValidArgs(info, rowBytes, &size) || !pixels) {
+ if (!SkImage_Raster::ValidArgs(info, rowBytes, NULL, &size) || !pixels) {
return NULL;
}
+ SkColorTable* ctable = NULL;
SkAutoDataUnref data(SkData::NewWithProc(pixels, size, proc, ctx));
- return SkNEW_ARGS(SkImage_Raster, (info, data, rowBytes, NULL));
+ return SkNEW_ARGS(SkImage_Raster, (info, data, rowBytes, ctable, NULL));
}
SkImage* SkImage::NewFromGenerator(SkImageGenerator* generator, const SkIRect* subset) {
SkImage* SkNewImageFromPixelRef(const SkImageInfo& info, SkPixelRef* pr,
const SkIPoint& pixelRefOrigin, size_t rowBytes,
const SkSurfaceProps* props) {
- if (!SkImage_Raster::ValidArgs(info, rowBytes, NULL)) {
+ if (!SkImage_Raster::ValidArgs(info, rowBytes, NULL, NULL)) {
return NULL;
}
return SkNEW_ARGS(SkImage_Raster, (info, pr, pixelRefOrigin, rowBytes, props));
SkImage* SkNewImageFromBitmap(const SkBitmap& bm, bool canSharePixelRef,
const SkSurfaceProps* props) {
- if (!SkImage_Raster::ValidArgs(bm.info(), bm.rowBytes(), NULL)) {
+ if (!SkImage_Raster::ValidArgs(bm.info(), bm.rowBytes(), NULL, NULL)) {
return NULL;
}
test_encode(reporter, ctx);
}
#endif
+
+DEF_TEST(Image_NewRasterCopy, reporter) {
+ const SkPMColor red = SkPackARGB32(0xFF, 0xFF, 0, 0);
+ const SkPMColor green = SkPackARGB32(0xFF, 0, 0xFF, 0);
+ const SkPMColor blue = SkPackARGB32(0xFF, 0, 0, 0xFF);
+ SkPMColor colors[] = { red, green, blue, 0 };
+ SkAutoTUnref<SkColorTable> ctable(SkNEW_ARGS(SkColorTable, (colors, SK_ARRAY_COUNT(colors))));
+ // The colortable made a copy, so we can trash the original colors
+ memset(colors, 0xFF, sizeof(colors));
+
+ const SkImageInfo srcInfo = SkImageInfo::Make(2, 2, kIndex_8_SkColorType, kPremul_SkAlphaType);
+ const size_t srcRowBytes = 2 * sizeof(uint8_t);
+ uint8_t indices[] = { 0, 1, 2, 3 };
+ SkAutoTUnref<SkImage> image(SkImage::NewRasterCopy(srcInfo, indices, srcRowBytes, ctable));
+ // The image made a copy, so we can trash the original indices
+ memset(indices, 0xFF, sizeof(indices));
+
+ const SkImageInfo dstInfo = SkImageInfo::MakeN32Premul(2, 2);
+ const size_t dstRowBytes = 2 * sizeof(SkPMColor);
+ SkPMColor pixels[4];
+ memset(pixels, 0xFF, sizeof(pixels)); // init with values we don't expect
+ image->readPixels(dstInfo, pixels, dstRowBytes, 0, 0);
+ REPORTER_ASSERT(reporter, red == pixels[0]);
+ REPORTER_ASSERT(reporter, green == pixels[1]);
+ REPORTER_ASSERT(reporter, blue == pixels[2]);
+ REPORTER_ASSERT(reporter, 0 == pixels[3]);
+}