bool SkImage_Gpu::onReadPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, int srcX, int srcY) const { GrPixelConfig config = SkImageInfo2GrPixelConfig(info.colorType(), info.alphaType(), info.profileType()); uint32_t flags = 0; if (kUnpremul_SkAlphaType == info.alphaType() && kPremul_SkAlphaType == fAlphaType) { // let the GPU perform this transformation for us flags = GrContext::kUnpremul_PixelOpsFlag; } if (!fTexture->readPixels(srcX, srcY, info.width(), info.height(), config, pixels, rowBytes, flags)) { return false; } // do we have to manually fix-up the alpha channel? // src dst // unpremul premul fix manually // premul unpremul done by kUnpremul_PixelOpsFlag // all other combos need to change. // // Should this be handled by Ganesh? todo:? // if (kPremul_SkAlphaType == info.alphaType() && kUnpremul_SkAlphaType == fAlphaType) { apply_premul(info, pixels, rowBytes); } return true; }
DEF_TEST(ColorSpace_Named, r) { const struct { SkColorSpace::Named fNamed; bool fExpectedToSucceed; bool fIsSRGB; } recs[] { { SkColorSpace::kUnknown_Named, false, false }, { SkColorSpace::kSRGB_Named, true, true }, { SkColorSpace::kAdobeRGB_Named, true, false }, }; for (auto rec : recs) { auto cs = SkColorSpace::NewNamed(rec.fNamed); REPORTER_ASSERT(r, !cs == !rec.fExpectedToSucceed); if (cs) { if (rec.fIsSRGB) { REPORTER_ASSERT(r, SkColorSpace::kSRGB_GammaNamed == cs->gammaNamed()); } else { REPORTER_ASSERT(r, SkColorSpace::k2Dot2Curve_GammaNamed == cs->gammaNamed()); } } } SkImageInfo info = SkImageInfo::MakeS32(10, 10, kPremul_SkAlphaType); REPORTER_ASSERT(r, kSRGB_SkColorProfileType == info.profileType()); REPORTER_ASSERT(r, SkColorSpace::kSRGB_GammaNamed == info.colorSpace()->gammaNamed()); }
/* * Checks if the conversion between the input image and the requested output * image has been implemented */ static bool conversion_possible(const SkImageInfo& dst, const SkImageInfo& src) { // Ensure that the profile type is unchanged if (dst.profileType() != src.profileType()) { return false; } // Ensure that the alpha type is opaque if (kOpaque_SkAlphaType != dst.alphaType()) { return false; } // Always allow kN32 as the color type if (kN32_SkColorType == dst.colorType()) { return true; } // Otherwise require that the destination color type match our recommendation return dst.colorType() == src.colorType(); }
/* * Checks if the conversion between the input image and the requested output * image has been implemented * Sets the output color space */ bool SkJpegCodec::setOutputColorSpace(const SkImageInfo& dst) { const SkImageInfo& src = this->getInfo(); // Ensure that the profile type is unchanged if (dst.profileType() != src.profileType()) { return false; } // Ensure that the alpha type is opaque if (kOpaque_SkAlphaType != dst.alphaType()) { return false; } // Check if we will decode to CMYK because a conversion to RGBA is not supported J_COLOR_SPACE colorSpace = fDecoderMgr->dinfo()->jpeg_color_space; bool isCMYK = JCS_CMYK == colorSpace || JCS_YCCK == colorSpace; // Check for valid color types and set the output color space switch (dst.colorType()) { case kN32_SkColorType: if (isCMYK) { fDecoderMgr->dinfo()->out_color_space = JCS_CMYK; } else { // Check the byte ordering of the RGBA color space for the // current platform #if defined(SK_PMCOLOR_IS_RGBA) fDecoderMgr->dinfo()->out_color_space = JCS_EXT_RGBA; #else fDecoderMgr->dinfo()->out_color_space = JCS_EXT_BGRA; #endif } return true; case kRGB_565_SkColorType: if (isCMYK) { fDecoderMgr->dinfo()->out_color_space = JCS_CMYK; } else { fDecoderMgr->dinfo()->dither_mode = JDITHER_NONE; fDecoderMgr->dinfo()->out_color_space = JCS_RGB565; } return true; case kGray_8_SkColorType: if (isCMYK) { return false; } else { // We will enable decodes to gray even if the image is color because this is // much faster than decoding to color and then converting fDecoderMgr->dinfo()->out_color_space = JCS_GRAYSCALE; } return true; default: return false; } }
static SkBitmap createBitmapWithSpace(const SkBitmap& bitmap, int spaceWidth, int spaceHeight) { SkImageInfo info = bitmap.info(); SkImageInfo newInfo = SkImageInfo::Make( info.width() + spaceWidth, info.height() + spaceHeight, info.colorType(), kPremul_SkAlphaType, info.profileType()); SkBitmap result; result.allocPixels(newInfo); result.eraseColor(SK_ColorTRANSPARENT); bitmap.copyPixelsTo(reinterpret_cast<uint8_t*>(result.getPixels()), result.rowBytes() * result.height(), result.rowBytes()); return result; }
static bool choose_linear_pipeline(const SkShader::ContextRec& rec, const SkImageInfo& srcInfo) { // These src attributes are not supported in the new 4f context (yet) // if (srcInfo.profileType() != kSRGB_SkColorProfileType) { return false; } if (srcInfo.colorType() != kRGBA_8888_SkColorType && srcInfo.colorType() != kBGRA_8888_SkColorType && srcInfo.colorType() != kIndex_8_SkColorType && srcInfo.colorType() != kRGBA_F16_SkColorType) { return false; } // If we get here, we can reasonably use either context, respect the caller's preference // return SkShader::ContextRec::kPM4f_DstType == rec.fPreferredDstType; }
/* * Checks if the conversion between the input image and the requested output * image has been implemented */ static bool conversion_possible(const SkImageInfo& dst, const SkImageInfo& src) { // Ensure that the profile type is unchanged if (dst.profileType() != src.profileType()) { return false; } // Ensure the alpha type is valid if (!valid_alpha(dst.alphaType(), src.alphaType())) { return false; } // Check for supported color types switch (dst.colorType()) { // Allow output to kN32 from any type of input case kN32_SkColorType: return true; // Allow output to kIndex_8 from compatible inputs case kIndex_8_SkColorType: return kIndex_8_SkColorType == src.colorType(); default: return false; } }
void HelloWorldWindow::draw(SkCanvas* canvas) { drawContents(canvas); // in case we have queued drawing calls fContext->flush(); // Invalidate the window to force a redraw. Poor man's animation mechanism. this->inval(NULL); if (kRaster_DeviceType == fType) { // need to send the raster bits to the (gpu) window SkImage* snap = fSurface->newImageSnapshot(); size_t rowBytes; SkImageInfo info; const void* pixels = snap->peekPixels(&info, &rowBytes); fRenderTarget->writePixels(0, 0, snap->width(), snap->height(), SkImageInfo2GrPixelConfig(info.colorType(), info.alphaType(), info.profileType()), pixels, rowBytes, GrContext::kFlushWrites_PixelOp); SkSafeUnref(snap); } INHERITED::present(); }
/* * Checks if the conversion between the input image and the requested output * image has been implemented * Sets the output color space */ bool SkJpegCodec::setOutputColorSpace(const SkImageInfo& dst) { const SkImageInfo& src = this->getInfo(); // Ensure that the profile type is unchanged if (dst.profileType() != src.profileType()) { return false; } if (kUnknown_SkAlphaType == dst.alphaType()) { return false; } if (kOpaque_SkAlphaType != dst.alphaType()) { SkCodecPrintf("Warning: an opaque image should be decoded as opaque " "- it is being decoded as non-opaque, which will draw slower\n"); } // Check if we will decode to CMYK because a conversion to RGBA is not supported J_COLOR_SPACE colorSpace = fDecoderMgr->dinfo()->jpeg_color_space; bool isCMYK = JCS_CMYK == colorSpace || JCS_YCCK == colorSpace; // Check for valid color types and set the output color space switch (dst.colorType()) { case kN32_SkColorType: if (isCMYK) { fDecoderMgr->dinfo()->out_color_space = JCS_CMYK; } else { #ifdef LIBJPEG_TURBO_VERSION // Check the byte ordering of the RGBA color space for the // current platform #ifdef SK_PMCOLOR_IS_RGBA fDecoderMgr->dinfo()->out_color_space = JCS_EXT_RGBA; #else fDecoderMgr->dinfo()->out_color_space = JCS_EXT_BGRA; #endif #else fDecoderMgr->dinfo()->out_color_space = JCS_RGB; #endif } return true; case kRGB_565_SkColorType: if (isCMYK) { fDecoderMgr->dinfo()->out_color_space = JCS_CMYK; } else { #ifdef TURBO_HAS_565 fDecoderMgr->dinfo()->dither_mode = JDITHER_NONE; fDecoderMgr->dinfo()->out_color_space = JCS_RGB565; #else fDecoderMgr->dinfo()->out_color_space = JCS_RGB; #endif } return true; case kGray_8_SkColorType: if (isCMYK) { return false; } else { // We will enable decodes to gray even if the image is color because this is // much faster than decoding to color and then converting fDecoderMgr->dinfo()->out_color_space = JCS_GRAYSCALE; } return true; default: return false; } }