static bool choose_blitprocs(const SkPM4f* pm4, const SkImageInfo& info, SkShader::Context::BlitState* state) { uint32_t flags = SkXfermode::kSrcIsSingle_D32Flag; if (pm4->a() == 1) { flags |= SkXfermode::kSrcIsOpaque_D32Flag; } switch (info.colorType()) { case kN32_SkColorType: if (info.gammaCloseToSRGB()) { flags |= SkXfermode::kDstIsSRGB_D32Flag; } state->fStorage[0] = (void*)SkXfermode::GetD32Proc(state->fXfer, flags); state->fStorage[1] = (void*)pm4; state->fBlitBW = D32_BlitBW; state->fBlitAA = D32_BlitAA; return true; case kRGBA_F16_SkColorType: state->fStorage[0] = (void*)SkXfermode::GetF16Proc(state->fXfer, flags); state->fStorage[1] = (void*)pm4; state->fBlitBW = F16_BlitBW; state->fBlitAA = F16_BlitAA; return true; default: return false; } }
bool SkLinearBitmapPipeline::ClonePipelineForBlitting( SkEmbeddableLinearPipeline* pipelineStorage, const SkLinearBitmapPipeline& pipeline, SkMatrix::TypeMask matrixMask, SkShader::TileMode xTileMode, SkShader::TileMode yTileMode, SkFilterQuality filterQuality, const SkPixmap& srcPixmap, float finalAlpha, SkXfermode::Mode xferMode, const SkImageInfo& dstInfo) { if (xferMode == SkXfermode::kSrcOver_Mode && srcPixmap.info().alphaType() == kOpaque_SkAlphaType) { xferMode = SkXfermode::kSrc_Mode; } if (matrixMask & ~SkMatrix::kTranslate_Mask ) { return false; } if (filterQuality != SkFilterQuality::kNone_SkFilterQuality) { return false; } if (finalAlpha != 1.0f) { return false; } if (srcPixmap.info().colorType() != kRGBA_8888_SkColorType || dstInfo.colorType() != kRGBA_8888_SkColorType) { return false; } if (!srcPixmap.info().gammaCloseToSRGB() || !dstInfo.gammaCloseToSRGB()) { return false; } if (xferMode != SkXfermode::kSrc_Mode && xferMode != SkXfermode::kSrcOver_Mode) { return false; } pipelineStorage->init(pipeline, srcPixmap, xferMode, dstInfo); return true; }
static bool supported(const SkImageInfo& info) { switch (info.colorType()) { case kAlpha_8_SkColorType: return true; case kRGB_565_SkColorType: return true; case kN32_SkColorType: return info.gammaCloseToSRGB(); case kRGBA_F16_SkColorType: return true; default: return false; } }
State32(const SkImageInfo& info, const SkPaint& paint, const SkShader::Context* shaderContext) : State4f(info, paint, shaderContext) { if (is_opaque(paint, shaderContext)) { fFlags |= SkXfermode::kSrcIsOpaque_D32Flag; } if (info.gammaCloseToSRGB()) { fFlags |= SkXfermode::kDstIsSRGB_D32Flag; } fProc1 = SkXfermode::GetD32Proc(fXfer, fFlags | SkXfermode::kSrcIsSingle_D32Flag); fProcN = SkXfermode::GetD32Proc(fXfer, fFlags); }
bool SkJpegEncoderMgr::setParams(const SkImageInfo& srcInfo, const SkJpegEncoder::Options& options) { auto chooseProc8888 = [&]() { if (kUnpremul_SkAlphaType != srcInfo.alphaType() || SkJpegEncoder::AlphaOption::kIgnore == options.fAlphaOption) { return (transform_scanline_proc) nullptr; } // Note that kRespect mode is only supported with sRGB or linear transfer functions. // The legacy code path is incidentally correct when the transfer function is linear. const bool isSRGBTransferFn = srcInfo.gammaCloseToSRGB() && (SkTransferFunctionBehavior::kRespect == options.fBlendBehavior); if (isSRGBTransferFn) { return transform_scanline_to_premul_linear; } else { return transform_scanline_to_premul_legacy; } }; J_COLOR_SPACE jpegColorType = JCS_EXT_RGBA; int numComponents = 0; switch (srcInfo.colorType()) { case kRGBA_8888_SkColorType: fProc = chooseProc8888(); jpegColorType = JCS_EXT_RGBA; numComponents = 4; break; case kBGRA_8888_SkColorType: fProc = chooseProc8888(); jpegColorType = JCS_EXT_BGRA; numComponents = 4; break; case kRGB_565_SkColorType: fProc = transform_scanline_565; jpegColorType = JCS_RGB; numComponents = 3; break; case kARGB_4444_SkColorType: if (SkJpegEncoder::AlphaOption::kBlendOnBlack == options.fAlphaOption) { return false; } fProc = transform_scanline_444; jpegColorType = JCS_RGB; numComponents = 3; break; case kGray_8_SkColorType: SkASSERT(srcInfo.isOpaque()); jpegColorType = JCS_GRAYSCALE; numComponents = 1; break; case kRGBA_F16_SkColorType: if (!srcInfo.colorSpace() || !srcInfo.colorSpace()->gammaIsLinear() || SkTransferFunctionBehavior::kRespect != options.fBlendBehavior) { return false; } if (kUnpremul_SkAlphaType != srcInfo.alphaType() || SkJpegEncoder::AlphaOption::kIgnore == options.fAlphaOption) { fProc = transform_scanline_F16_to_8888; } else { fProc = transform_scanline_F16_to_premul_8888; } jpegColorType = JCS_EXT_RGBA; numComponents = 4; break; default: return false; } fCInfo.image_width = srcInfo.width(); fCInfo.image_height = srcInfo.height(); fCInfo.in_color_space = jpegColorType; fCInfo.input_components = numComponents; jpeg_set_defaults(&fCInfo); if (kGray_8_SkColorType != srcInfo.colorType()) { switch (options.fDownsample) { case SkJpegEncoder::Downsample::k420: SkASSERT(2 == fCInfo.comp_info[0].h_samp_factor); SkASSERT(2 == fCInfo.comp_info[0].v_samp_factor); SkASSERT(1 == fCInfo.comp_info[1].h_samp_factor); SkASSERT(1 == fCInfo.comp_info[1].v_samp_factor); SkASSERT(1 == fCInfo.comp_info[2].h_samp_factor); SkASSERT(1 == fCInfo.comp_info[2].v_samp_factor); break; case SkJpegEncoder::Downsample::k422: fCInfo.comp_info[0].h_samp_factor = 2; fCInfo.comp_info[0].v_samp_factor = 1; fCInfo.comp_info[1].h_samp_factor = 1; fCInfo.comp_info[1].v_samp_factor = 1; fCInfo.comp_info[2].h_samp_factor = 1; fCInfo.comp_info[2].v_samp_factor = 1; break; case SkJpegEncoder::Downsample::k444: fCInfo.comp_info[0].h_samp_factor = 1; fCInfo.comp_info[0].v_samp_factor = 1; fCInfo.comp_info[1].h_samp_factor = 1; fCInfo.comp_info[1].v_samp_factor = 1; fCInfo.comp_info[2].h_samp_factor = 1; fCInfo.comp_info[2].v_samp_factor = 1; break; } } // Tells libjpeg-turbo to compute optimal Huffman coding tables // for the image. This improves compression at the cost of // slower encode performance. fCInfo.optimize_coding = TRUE; return true; }