#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include "third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder.h"
#include <limits>
#include <memory>
#include "base/logging.h"
#include "base/memory/raw_ptr.h"
#include "base/numerics/checked_math.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "third_party/blink/renderer/platform/graphics/bitmap_image_metrics.h"
#include "third_party/skia/include/core/SkColorSpace.h"
#include "third_party/skia/include/private/SkJpegMetadataDecoder.h"
extern "C" {
#include <setjmp.h>
#include <stdio.h>
#include "jpeglib.h"
}
#if defined(ARCH_CPU_BIG_ENDIAN)
#error Blink assumes a little-endian target.
#endif
#if defined(JCS_ALPHA_EXTENSIONS)
#define TURBO_JPEG_RGB_SWIZZLE
#if SK_B32_SHIFT
inline J_COLOR_SPACE rgbOutputColorSpace() {
return JCS_EXT_RGBA;
}
#else
inline J_COLOR_SPACE rgbOutputColorSpace() { … }
#endif
inline bool turboSwizzled(J_COLOR_SPACE colorSpace) { … }
#else
inline J_COLOR_SPACE rgbOutputColorSpace() {
return JCS_RGB;
}
#endif
namespace {
const unsigned g_scale_denominator = …;
cc::YUVSubsampling YuvSubsampling(const jpeg_decompress_struct& info) { … }
bool SubsamplingSupportedByDecodeToYUV(cc::YUVSubsampling subsampling) { … }
int Align(int size, int alignment) { … }
}
namespace blink {
struct decoder_error_mgr { … };
struct decoder_source_mgr { … };
enum jstate { … };
void init_source(j_decompress_ptr jd);
boolean fill_input_buffer(j_decompress_ptr jd);
void skip_input_data(j_decompress_ptr jd, long num_bytes);
void term_source(j_decompress_ptr jd);
void error_exit(j_common_ptr cinfo);
void emit_message(j_common_ptr cinfo, int msg_level);
static gfx::Size ComputeYUVSize(const jpeg_decompress_struct* info,
int component) { … }
static wtf_size_t ComputeYUVWidthBytes(const jpeg_decompress_struct* info,
int component) { … }
static void ProgressMonitor(j_common_ptr info) { … }
class JPEGImageReader final { … };
void error_exit(
j_common_ptr cinfo)
{ … }
void emit_message(j_common_ptr cinfo, int msg_level) { … }
void init_source(j_decompress_ptr) { … }
void skip_input_data(j_decompress_ptr jd, long num_bytes) { … }
boolean fill_input_buffer(j_decompress_ptr jd) { … }
void term_source(j_decompress_ptr jd) { … }
JPEGImageDecoder::JPEGImageDecoder(AlphaOption alpha_option,
ColorBehavior color_behavior,
cc::AuxImage aux_image,
wtf_size_t max_decoded_bytes,
wtf_size_t offset)
: … { … }
JPEGImageDecoder::~JPEGImageDecoder() = default;
String JPEGImageDecoder::FilenameExtension() const { … }
const AtomicString& JPEGImageDecoder::MimeType() const { … }
bool JPEGImageDecoder::SetSize(unsigned width, unsigned height) { … }
void JPEGImageDecoder::OnSetData(scoped_refptr<SegmentReader> data) { … }
gfx::Size JPEGImageDecoder::DecodedSize() const { … }
void JPEGImageDecoder::SetDecodedSize(unsigned width, unsigned height) { … }
cc::YUVSubsampling JPEGImageDecoder::GetYUVSubsampling() const { … }
gfx::Size JPEGImageDecoder::DecodedYUVSize(cc::YUVIndex index) const { … }
wtf_size_t JPEGImageDecoder::DecodedYUVWidthBytes(cc::YUVIndex index) const { … }
unsigned JPEGImageDecoder::DesiredScaleNumerator() const { … }
unsigned JPEGImageDecoder::DesiredScaleNumerator(wtf_size_t max_decoded_bytes,
wtf_size_t original_bytes,
unsigned scale_denominator) { … }
bool JPEGImageDecoder::ShouldGenerateAllSizes() const { … }
void JPEGImageDecoder::DecodeToYUV() { … }
SkYUVColorSpace JPEGImageDecoder::GetYUVColorSpace() const { … }
void JPEGImageDecoder::SetSupportedDecodeSizes(Vector<SkISize> sizes) { … }
Vector<SkISize> JPEGImageDecoder::GetSupportedDecodeSizes() const { … }
bool JPEGImageDecoder::GetGainmapInfoAndData(
SkGainmapInfo& out_gainmap_info,
scoped_refptr<SegmentReader>& out_gainmap_data) const { … }
gfx::Size JPEGImageDecoder::GetImageCodedSize() const { … }
void JPEGImageDecoder::DecodeSize() { … }
void JPEGImageDecoder::Decode(wtf_size_t) { … }
cc::ImageHeaderMetadata JPEGImageDecoder::MakeMetadataForDecodeAcceleration()
const { … }
template <J_COLOR_SPACE colorSpace>
void SetPixel(ImageFrame::PixelData*, JSAMPARRAY samples, int column) = delete;
template <>
void SetPixel<JCS_RGB>(ImageFrame::PixelData* pixel,
JSAMPARRAY samples,
int column) { … }
template <>
void SetPixel<JCS_CMYK>(ImageFrame::PixelData* pixel,
JSAMPARRAY samples,
int column) { … }
template <J_COLOR_SPACE colorSpace>
bool OutputRows(JPEGImageReader* reader, ImageFrame& buffer) { … }
static bool OutputRawData(JPEGImageReader* reader, ImagePlanes* image_planes) { … }
bool JPEGImageDecoder::OutputScanlines() { … }
void JPEGImageDecoder::Complete() { … }
inline bool IsComplete(const JPEGImageDecoder* decoder,
JPEGImageDecoder::DecodingMode decoding_mode) { … }
void JPEGImageDecoder::Decode(DecodingMode decoding_mode) { … }
}