// BitmapFactory
  public static Bitmap decodeStream(InputStream is, Rect outPadding, Options opts) {
    // ...
    return decodeStreamInternal(is, outPadding, opts);
  }
  private static Bitmap decodeStreamInternal(InputStream is, Rect outPadding, Options opts) {
    // ...
    // Native 方法
    byte [] tempStorage = new byte[DECODE_BUFFER_SIZE];
    return nativeDecodeStream(is, tempStorage, outPadding, opts);
  }
  //BitmapFactory.cpp
  static jobject nativeDecodeStream(JNIEnv *env, jobject clazz, jobject is, jbyteArray storage, jobject padding, jobject options) {
    // ...
    return doDecode(env, bufferedStream.release(), padding, options);
  }
  static jobject doDecode(JNIEnv *env, SkStreamRewindable *stream, jobject padding, jobject options) {
    ...
    // 创建解码器
    std::unique_ptr<SkAndroidCodec> codec(SkAndroidCodec::NewFromStream(streamDeleter.release(), &peeker));
    ...
    // 输出Bitmap的色彩类型
    SkColorType decodeColorType = codec->computeOutputColorType(prefColorType);
    ...
    // SkAndroidCodec完成解码
    SkCodec::Result result = codec->getAndroidPixels(
        decodeInfo,                 // 解码信息 (长度, 宽度, 色彩类型, 透明度等)
        decodingBitmap.getPixels(), // Bitmap 的实际内存地址, 即像素们的内存地址
        decodingBitmap.rowBytes(),  // 每一行的大小, 即每一行所有像素的大小
        &codecOptions);             // 解码器配置 (色码表, 采样大小等)
    ...
  }
  // SkAndroidCodec.cpp
  SkCodec::Result SkAndroidCodec::getAndroidPixels(const SkImageInfo &info, void *pixels, size_t rowBytes, const AndroidOptions *options)
  {
      // ...
      return this->onGetAndroidPixels(info, pixels, rowBytes, *options);
  }
  SkCodec::Result SkSampledCodec::onGetAndroidPixels(const SkImageInfo &info, void *pixels, size_t rowBytes, const AndroidOptions &options)
{
    ...
    SkCodec::Result result = this->codec()->startScanlineDecode(info.makeWH(scaledSize.width, scaledSize.height()),&codecOptions, options.fColorPtr, options.fColorCount);
    ...
}
SkCodec::Result SkCodec::startScanlineDecode(const SkImageInfo &dstInfo, const SkCodec::Options *options, SkPMColor ctable[], int *ctableCount) {
    ...
    // 逐行解码并写入内存
    const Result result = this->onStartScanlineDecode(dstInfo, *options, ctable, ctableCount);
    ...
    // [02] 实际执行逐行解码, 并将结果写入对应的内存地址
    switch (this->codec()->getScanlineOrder()) {
        case SkCodec::kTopDown_SkScanlineOrder:
        case SkCodec::kNone_SkScanlineOrder: {
            // ...
            int decodedLines = this->codec()->getScanlines(pixels, scaledSubsetHeight, rowBytes);
            // ...
            return SkCodec::kSuccess;
        }
        ...
    }
}
// SkJpegCodec.cpp
// 通过jpeglib进行解码
int SkJpegCodec::onGetScanlines(void *dst, int count, size_t dstRowBytes) {
    ...
    for (int y = 0; y < count; y++)
    {
        // 逐行解压 & 读取像素, jpeglib 的方法
        uint32_t rowsDecoded = jpeg_read_scanlines(fDecoderMgr->dinfo(), &dstRow, 1);
        ...
    }
    ...
}