diff --git a/blink/renderer/platform/image-decoders/heif/heif_image_decoder.cc b/blink/renderer/platform/image-decoders/heif/heif_image_decoder.cc index e383bddd72f886bc4b38610a2690e3b3ececb333..765c90d16eb517fbb3f5845b8d56f032a5c79501 100644 --- a/blink/renderer/platform/image-decoders/heif/heif_image_decoder.cc +++ b/blink/renderer/platform/image-decoders/heif/heif_image_decoder.cc @@ -225,6 +225,7 @@ void HEIFImageDecoder::OnSetData(SegmentReader* data) { << " * " << GetDecoderAdapter()->GetImageHeight(); SetSize(GetDecoderAdapter()->GetImageWidth(), GetDecoderAdapter()->GetImageHeight()); + data_ = data; return; } LOG(ERROR) << "[HeifSupport] Fail to parsing image information. "; @@ -296,7 +297,82 @@ wtf_size_t HEIFImageDecoder::DecodeFrameCount() { void HEIFImageDecoder::InitializeNewFrame(wtf_size_t index) {} -void HEIFImageDecoder::Decode(wtf_size_t index) {} +void HEIFImageDecoder::Decode(wtf_size_t index) { + if (frame_buffer_cache_.empty()) { + LOG(ERROR) << "[HeifSupport] HEIFImageDecoder::Decode frame_buffer_cache is empty."; + SetFailed(); + return; + } + + const char* segment = nullptr; + const size_t bytes = data_->GetSomeData(segment, 0); + if (segment == nullptr || bytes == 0) { + LOG(ERROR) << "[HeifSupport] HEIFImageDecoder::Decode GetSomeData failed."; + SetFailed(); + return; + } + + bool decode_rst = GetDecoderAdapter()->Decode((const uint8_t*)segment, (uint32_t)data_->size(), + OHOS::NWeb::AllocatorType::kShareMemAlloc, false); + if (!decode_rst) { + LOG(ERROR) << "[HeifSupport] HEIFImageDecoder::Decode Decode failed."; + SetFailed(); + return; + } + LOG(DEBUG) << "[HeifSupport] HEIFImageDecoder::Decode GetDecoderAdapter()->Decode succeed." + + void *ptr = GetDecoderAdapter()->GetDecodeData(); + if (ptr == nullptr) { + LOG(ERROR) << "[HeifSupport] HEIFImageDecoder::Decode GetDecodeData failed."; + SetFailed(); + return; + } + + if (!InitFrameBuffer(index)) { + LOG(ERROR) << "[HeifSupport] HEIFImageDecoder::Decode InitFrameBuffer failed."; + SetFailed(); + return; + } + + ImageFrame& buffer = frame_buffer_cache_[index]; + ImageFrame::PixelData* pixel = buffer.GerAddr(0, 0); + if (pixel == nullptr) { + LOG(ERROR) << "[HeifSupport] HEIFImageDecoder::Decode GerAddr failed."; + SetFailed(); + return; + } + + int stride = GetDecoderAdapter()->GetPixelMapStride(); + if (stride <= 0) { + LOG(ERROR) << "[HeifSupport] HEIFImageDecoder::Decode stride error. stride = " << stride; + SetFailed(); + return; + } + + int width = buffer.Bitmap().width(); + int height = buffer.Bitmap().height(); + int rowBytes = buffer.Bitmap().rowBytes(); + int bytesPerPixel = buffer.Bitmap().bytesPerPixel(); + for (int i = 0; i < height; i++) { + if (memcpy_s((uint8_t*)pixel + i * width * bytesPerPixel, rowBytes, + (uint8_t*)ptr + i * stride, width * bytesPerPixel) != EOK) { + LOG(ERROR) << "[HeifSupport] HEIFImageDecoder::Decode memcpy failed." + << "width = " << width + << ", height = " << height + << ", rowBytes = " << rowBytes + << ", bytesPerPixel = " << bytesPerPixel + << ", stride = " << stride; + SetFailed(); + return; + } + } + + GetDecoderAdapter()->ReleasePixelMap(); + + buffer.SetPixelsChanged(true); + buffer.SetStatus(ImageFrame::kFrameComplete); + LOG(DEBUG) << "[HeifSupport] HEIFImageDecoder::Decode decode complete." +} bool HEIFImageDecoder::CanReusePreviousFrameBuffer(wtf_size_t index) const { return true; diff --git a/blink/renderer/platform/image-decoders/heif/heif_image_decoder.h b/blink/renderer/platform/image-decoders/heif/heif_image_decoder.h index f0027e8734f391193b495245c748d540a5501944..7589f87ccd680b75e14453a3440035e7ae002420 100644 --- a/blink/renderer/platform/image-decoders/heif/heif_image_decoder.h +++ b/blink/renderer/platform/image-decoders/heif/heif_image_decoder.h @@ -67,6 +67,7 @@ class PLATFORM_EXPORT HEIFImageDecoder final : public ImageDecoder { static OHOS::NWeb::OhosImageDecoderAdapter* GetDecoderAdapter(); private: + scoped_refptr data_; // ImageDecoder: void DecodeSize() override; wtf_size_t DecodeFrameCount() override;