| 365 | } |
| 366 | |
| 367 | bool ImageReader::decode_bytes(const uint8_t* data, size_t size, image_data_t& out_image) { |
| 368 | int codec_id = AV_CODEC_ID_NONE; |
| 369 | // header_print_g("DEBUG", "Decoding image of size: " << std::to_string(size) << " bytes"); |
| 370 | if (!parse_image_header(data, size, codec_id)) { |
| 371 | std::cerr << "Error: Unsupported image format (only JPEG/JPG and PNG supported)" << std::endl; |
| 372 | return false; |
| 373 | } |
| 374 | |
| 375 | if (!has_basic_image_integrity(data, size, codec_id)) { |
| 376 | std::cerr << "Error: Image payload failed integrity check" << std::endl; |
| 377 | return false; |
| 378 | } |
| 379 | |
| 380 | reset_decode_resources(); |
| 381 | |
| 382 | if (!ensure_decode_resources(codec_id)) { |
| 383 | std::cerr << "Error: Could not initialize FFmpeg decode objects" << std::endl; |
| 384 | return false; |
| 385 | } |
| 386 | |
| 387 | bool ok = false; |
| 388 | do { |
| 389 | av_frame_unref(frame_); |
| 390 | av_frame_unref(rgb_frame_); |
| 391 | av_packet_unref(packet_); |
| 392 | |
| 393 | packet_->data = const_cast<uint8_t*>(data); |
| 394 | packet_->size = static_cast<int>(size); |
| 395 | |
| 396 | if (avcodec_send_packet(codec_ctx_, packet_) < 0) { |
| 397 | std::cerr << "Error: Could not send packet for decoding" << std::endl; |
| 398 | break; |
| 399 | } |
| 400 | |
| 401 | if (avcodec_receive_frame(codec_ctx_, frame_) < 0) { |
| 402 | std::cerr << "Error: Could not decode image frame" << std::endl; |
| 403 | break; |
| 404 | } |
| 405 | |
| 406 | AVPixelFormat src_fmt = AV_PIX_FMT_NONE; |
| 407 | int src_full_range = 0; |
| 408 | resolve_source_format_and_range(static_cast<AVPixelFormat>(frame_->format), |
| 409 | src_fmt, |
| 410 | src_full_range, |
| 411 | frame_->color_range, |
| 412 | codec_ctx_->codec_id); |
| 413 | |
| 414 | const bool need_rebuild_sws = !sws_ctx_ || |
| 415 | sws_src_w_ != frame_->width || |
| 416 | sws_src_h_ != frame_->height || |
| 417 | sws_src_fmt_ != static_cast<int>(src_fmt) || |
| 418 | sws_src_range_ != src_full_range; |
| 419 | if (need_rebuild_sws) { |
| 420 | if (sws_ctx_) { |
| 421 | sws_freeContext(sws_ctx_); |
| 422 | sws_ctx_ = nullptr; |
| 423 | } |
| 424 |
nothing calls this directly
no test coverage detected