// 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);
...
}
...
}