std::unique_ptr SkSwizzler::Make()

in src/codec/SkSwizzler.cpp [829:1167]


std::unique_ptr<SkSwizzler> SkSwizzler::Make(const SkEncodedInfo& encodedInfo,
                                             const SkPMColor* ctable,
                                             const SkImageInfo& dstInfo,
                                             const SkCodec::Options& options,
                                             const SkIRect* frame) {
    if (SkEncodedInfo::kPalette_Color == encodedInfo.color() && nullptr == ctable) {
        return nullptr;
    }

    RowProc fastProc = nullptr;
    RowProc proc = nullptr;
    SkCodec::ZeroInitialized zeroInit = options.fZeroInitialized;
    const bool premultiply = (SkEncodedInfo::kOpaque_Alpha != encodedInfo.alpha()) &&
            (kPremul_SkAlphaType == dstInfo.alphaType());

    switch (encodedInfo.color()) {
        case SkEncodedInfo::kGray_Color:
            switch (encodedInfo.bitsPerComponent()) {
                case 1:
                    switch (dstInfo.colorType()) {
                        case kRGBA_8888_SkColorType:
                        case kBGRA_8888_SkColorType:
                            proc = &swizzle_bit_to_n32;
                            break;
                        case kRGB_565_SkColorType:
                            proc = &swizzle_bit_to_565;
                            break;
                        case kGray_8_SkColorType:
                            proc = &swizzle_bit_to_grayscale;
                            break;
                        case kRGBA_F16_SkColorType:
                            proc = &swizzle_bit_to_f16;
                            break;
                        default:
                            return nullptr;
                    }
                    break;
                case 8:
                    switch (dstInfo.colorType()) {
                        case kRGBA_8888_SkColorType:
                        case kBGRA_8888_SkColorType:
                            proc = &swizzle_gray_to_n32;
                            fastProc = &fast_swizzle_gray_to_n32;
                            break;
                        case kGray_8_SkColorType:
                            proc = &sample1;
                            fastProc = &copy;
                            break;
                        case kRGB_565_SkColorType:
                            proc = &swizzle_gray_to_565;
                            break;
                        default:
                            return nullptr;
                    }
                    break;
                default:
                    return nullptr;
            }
            break;
        case SkEncodedInfo::kXAlpha_Color:
        case SkEncodedInfo::kGrayAlpha_Color:
            switch (dstInfo.colorType()) {
                case kRGBA_8888_SkColorType:
                case kBGRA_8888_SkColorType:
                    if (premultiply) {
                        if (SkCodec::kYes_ZeroInitialized == zeroInit) {
                            proc = &SkipLeadingGrayAlphaZerosThen
                                    <swizzle_grayalpha_to_n32_premul>;
                            fastProc = &SkipLeadingGrayAlphaZerosThen
                                    <fast_swizzle_grayalpha_to_n32_premul>;
                        } else {
                            proc = &swizzle_grayalpha_to_n32_premul;
                            fastProc = &fast_swizzle_grayalpha_to_n32_premul;
                        }
                    } else {
                        if (SkCodec::kYes_ZeroInitialized == zeroInit) {
                            proc = &SkipLeadingGrayAlphaZerosThen
                                    <swizzle_grayalpha_to_n32_unpremul>;
                            fastProc = &SkipLeadingGrayAlphaZerosThen
                                    <fast_swizzle_grayalpha_to_n32_unpremul>;
                        } else {
                            proc = &swizzle_grayalpha_to_n32_unpremul;
                            fastProc = &fast_swizzle_grayalpha_to_n32_unpremul;
                        }
                    }
                    break;
                case kAlpha_8_SkColorType:
                    proc = &swizzle_grayalpha_to_a8;
                    break;
                default:
                    return nullptr;
            }
            break;
        case SkEncodedInfo::kPalette_Color:
            // We assume that the color table is premultiplied and swizzled
            // as desired.
            switch (encodedInfo.bitsPerComponent()) {
                case 1:
                case 2:
                case 4:
                    switch (dstInfo.colorType()) {
                        case kRGBA_8888_SkColorType:
                        case kBGRA_8888_SkColorType:
                            proc = &swizzle_small_index_to_n32;
                            break;
                        case kRGB_565_SkColorType:
                            proc = &swizzle_small_index_to_565;
                            break;
                        default:
                            return nullptr;
                    }
                    break;
                case 8:
                    switch (dstInfo.colorType()) {
                        case kRGBA_8888_SkColorType:
                        case kBGRA_8888_SkColorType:
                        case kBGR_101010x_XR_SkColorType:
                            if (SkCodec::kYes_ZeroInitialized == zeroInit) {
                                proc = &swizzle_index_to_n32_skipZ;
                            } else {
                                proc = &swizzle_index_to_n32;
                            }
                            break;
                        case kRGB_565_SkColorType:
                            proc = &swizzle_index_to_565;
                            break;
                        default:
                            return nullptr;
                    }
                    break;
                default:
                    return nullptr;
            }
            break;
        case SkEncodedInfo::k565_Color:
            // Treat 565 exactly like RGB (since it's still encoded as 8 bits per component).
            // We just mark as 565 when we have a hint that there are only 5/6/5 "significant"
            // bits in each channel.
        case SkEncodedInfo::kRGB_Color:
            switch (dstInfo.colorType()) {
                case kRGBA_8888_SkColorType:
                    if (16 == encodedInfo.bitsPerComponent()) {
                        proc = &swizzle_rgb16_to_rgba;
                        break;
                    }

                    SkASSERT(8 == encodedInfo.bitsPerComponent());
                    proc = &swizzle_rgb_to_rgba;
                    fastProc = &fast_swizzle_rgb_to_rgba;
                    break;
                case kBGRA_8888_SkColorType:
                    if (16 == encodedInfo.bitsPerComponent()) {
                        proc = &swizzle_rgb16_to_bgra;
                        break;
                    }

                    SkASSERT(8 == encodedInfo.bitsPerComponent());
                    proc = &swizzle_rgb_to_bgra;
                    fastProc = &fast_swizzle_rgb_to_bgra;
                    break;
                case kRGB_565_SkColorType:
                    if (16 == encodedInfo.bitsPerComponent()) {
                        proc = &swizzle_rgb16_to_565;
                        break;
                    }

                    proc = &swizzle_rgb_to_565;
                    break;
                default:
                    return nullptr;
            }
            break;
        case SkEncodedInfo::kRGBA_Color:
            switch (dstInfo.colorType()) {
                case kRGBA_8888_SkColorType:
                    if (16 == encodedInfo.bitsPerComponent()) {
                        proc = premultiply ? &swizzle_rgba16_to_rgba_premul :
                                             &swizzle_rgba16_to_rgba_unpremul;
                        break;
                    }

                    SkASSERT(8 == encodedInfo.bitsPerComponent());
                    if (premultiply) {
                        if (SkCodec::kYes_ZeroInitialized == zeroInit) {
                            proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_rgba_premul>;
                            fastProc = &SkipLeading8888ZerosThen
                                    <fast_swizzle_rgba_to_rgba_premul>;
                        } else {
                            proc = &swizzle_rgba_to_rgba_premul;
                            fastProc = &fast_swizzle_rgba_to_rgba_premul;
                        }
                    } else {
                        if (SkCodec::kYes_ZeroInitialized == zeroInit) {
                            proc = &SkipLeading8888ZerosThen<sample4>;
                            fastProc = &SkipLeading8888ZerosThen<copy>;
                        } else {
                            proc = &sample4;
                            fastProc = &copy;
                        }
                    }
                    break;
                case kBGRA_8888_SkColorType:
                    if (16 == encodedInfo.bitsPerComponent()) {
                        proc = premultiply ? &swizzle_rgba16_to_bgra_premul :
                                             &swizzle_rgba16_to_bgra_unpremul;
                        break;
                    }

                    SkASSERT(8 == encodedInfo.bitsPerComponent());
                    if (premultiply) {
                        if (SkCodec::kYes_ZeroInitialized == zeroInit) {
                            proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_premul>;
                            fastProc = &SkipLeading8888ZerosThen
                                    <fast_swizzle_rgba_to_bgra_premul>;
                        } else {
                            proc = &swizzle_rgba_to_bgra_premul;
                            fastProc = &fast_swizzle_rgba_to_bgra_premul;
                        }
                    } else {
                        if (SkCodec::kYes_ZeroInitialized == zeroInit) {
                            proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_unpremul>;
                            fastProc = &SkipLeading8888ZerosThen
                                    <fast_swizzle_rgba_to_bgra_unpremul>;
                        } else {
                            proc = &swizzle_rgba_to_bgra_unpremul;
                            fastProc = &fast_swizzle_rgba_to_bgra_unpremul;
                        }
                    }
                    break;
                default:
                    return nullptr;
            }
            break;
        case SkEncodedInfo::kBGR_Color:
            switch (dstInfo.colorType()) {
                case kBGRA_8888_SkColorType:
                    proc = &swizzle_rgb_to_rgba;
                    fastProc = &fast_swizzle_rgb_to_rgba;
                    break;
                case kRGBA_8888_SkColorType:
                    proc = &swizzle_rgb_to_bgra;
                    fastProc = &fast_swizzle_rgb_to_bgra;
                    break;
                case kRGB_565_SkColorType:
                    proc = &swizzle_bgr_to_565;
                    break;
                default:
                    return nullptr;
            }
            break;
        case SkEncodedInfo::kBGRX_Color:
            switch (dstInfo.colorType()) {
                case kBGRA_8888_SkColorType:
                    proc = &swizzle_rgb_to_rgba;
                    break;
                case kRGBA_8888_SkColorType:
                    proc = &swizzle_rgb_to_bgra;
                    break;
                case kRGB_565_SkColorType:
                    proc = &swizzle_bgr_to_565;
                    break;
                default:
                    return nullptr;
            }
            break;
        case SkEncodedInfo::kBGRA_Color:
            switch (dstInfo.colorType()) {
                case kBGRA_8888_SkColorType:
                    if (premultiply) {
                        if (SkCodec::kYes_ZeroInitialized == zeroInit) {
                            proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_rgba_premul>;
                            fastProc = &SkipLeading8888ZerosThen
                                    <fast_swizzle_rgba_to_rgba_premul>;
                        } else {
                            proc = &swizzle_rgba_to_rgba_premul;
                            fastProc = &fast_swizzle_rgba_to_rgba_premul;
                        }
                    } else {
                        if (SkCodec::kYes_ZeroInitialized == zeroInit) {
                            proc = &SkipLeading8888ZerosThen<sample4>;
                            fastProc = &SkipLeading8888ZerosThen<copy>;
                        } else {
                            proc = &sample4;
                            fastProc = &copy;
                        }
                    }
                    break;
                case kRGBA_8888_SkColorType:
                    if (premultiply) {
                        if (SkCodec::kYes_ZeroInitialized == zeroInit) {
                            proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_premul>;
                            fastProc = &SkipLeading8888ZerosThen
                                    <fast_swizzle_rgba_to_bgra_premul>;
                        } else {
                            proc = &swizzle_rgba_to_bgra_premul;
                            fastProc = &fast_swizzle_rgba_to_bgra_premul;
                        }
                    } else {
                        if (SkCodec::kYes_ZeroInitialized == zeroInit) {
                            proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_unpremul>;
                            fastProc = &SkipLeading8888ZerosThen
                                    <fast_swizzle_rgba_to_bgra_unpremul>;
                        } else {
                            proc = &swizzle_rgba_to_bgra_unpremul;
                            fastProc = &fast_swizzle_rgba_to_bgra_unpremul;
                        }
                    }
                    break;
                default:
                    return nullptr;
            }
            break;
        case SkEncodedInfo::kInvertedCMYK_Color:
            switch (dstInfo.colorType()) {
                case kRGBA_8888_SkColorType:
                    proc = &swizzle_cmyk_to_rgba;
                    fastProc = &fast_swizzle_cmyk_to_rgba;
                    break;
                case kBGRA_8888_SkColorType:
                    proc = &swizzle_cmyk_to_bgra;
                    fastProc = &fast_swizzle_cmyk_to_bgra;
                    break;
                case kRGB_565_SkColorType:
                    proc = &swizzle_cmyk_to_565;
                    break;
                default:
                    return nullptr;
            }
            break;
        default:
            return nullptr;
    }

    // Store bpp in bytes if it is an even multiple, otherwise use bits
    uint8_t bitsPerPixel = encodedInfo.bitsPerPixel();
    int srcBPP = SkIsAlign8(bitsPerPixel) ? bitsPerPixel / 8 : bitsPerPixel;
    int dstBPP = dstInfo.bytesPerPixel();
    return Make(dstInfo, fastProc, proc, ctable, srcBPP, dstBPP, options, frame);
}