Flutter Engine
The Flutter Engine
Public Member Functions | Static Public Member Functions | Protected Member Functions | Friends | List of all members
SkJpegCodec Class Reference

#include <SkJpegCodec.h>

Inheritance diagram for SkJpegCodec:
SkCodec SkNoncopyable

Public Member Functions

 ~SkJpegCodec () override
 
- Public Member Functions inherited from SkCodec
virtual ~SkCodec ()
 
SkImageInfo getInfo () const
 
SkISize dimensions () const
 
SkIRect bounds () const
 
const skcms_ICCProfilegetICCProfile () const
 
SkEncodedOrigin getOrigin () const
 
SkISize getScaledDimensions (float desiredScale) const
 
bool getValidSubset (SkIRect *desiredSubset) const
 
SkEncodedImageFormat getEncodedFormat () const
 
virtual std::unique_ptr< SkStreamgetEncodedData () const
 
Result getPixels (const SkImageInfo &info, void *pixels, size_t rowBytes, const Options *)
 
Result getPixels (const SkImageInfo &info, void *pixels, size_t rowBytes)
 
Result getPixels (const SkPixmap &pm, const Options *opts=nullptr)
 
std::tuple< sk_sp< SkImage >, SkCodec::ResultgetImage (const SkImageInfo &info, const Options *opts=nullptr)
 
std::tuple< sk_sp< SkImage >, SkCodec::ResultgetImage ()
 
bool queryYUVAInfo (const SkYUVAPixmapInfo::SupportedDataTypes &supportedDataTypes, SkYUVAPixmapInfo *yuvaPixmapInfo) const
 
Result getYUVAPlanes (const SkYUVAPixmaps &yuvaPixmaps)
 
Result startIncrementalDecode (const SkImageInfo &dstInfo, void *dst, size_t rowBytes, const Options *)
 
Result startIncrementalDecode (const SkImageInfo &dstInfo, void *dst, size_t rowBytes)
 
Result incrementalDecode (int *rowsDecoded=nullptr)
 
Result startScanlineDecode (const SkImageInfo &dstInfo, const Options *options)
 
Result startScanlineDecode (const SkImageInfo &dstInfo)
 
int getScanlines (void *dst, int countLines, size_t rowBytes)
 
bool skipScanlines (int countLines)
 
SkScanlineOrder getScanlineOrder () const
 
int nextScanline () const
 
int outputScanline (int inputScanline) const
 
int getFrameCount ()
 
bool getFrameInfo (int index, FrameInfo *info) const
 
std::vector< FrameInfogetFrameInfo ()
 
int getRepetitionCount ()
 

Static Public Member Functions

static bool IsJpeg (const void *, size_t)
 
static std::unique_ptr< SkCodecMakeFromStream (std::unique_ptr< SkStream >, Result *)
 
- Static Public Member Functions inherited from SkCodec
static constexpr size_t MinBufferedBytesNeeded ()
 
static const char * ResultToString (Result)
 
static std::unique_ptr< SkCodecMakeFromStream (std::unique_ptr< SkStream >, SkSpan< const SkCodecs::Decoder > decoders, Result *=nullptr, SkPngChunkReader *=nullptr, SelectionPolicy selectionPolicy=SelectionPolicy::kPreferStillImage)
 
static std::unique_ptr< SkCodecMakeFromStream (std::unique_ptr< SkStream >, Result *=nullptr, SkPngChunkReader *=nullptr, SelectionPolicy selectionPolicy=SelectionPolicy::kPreferStillImage)
 
static std::unique_ptr< SkCodecMakeFromData (sk_sp< SkData >, SkSpan< const SkCodecs::Decoder > decoders, SkPngChunkReader *=nullptr)
 
static std::unique_ptr< SkCodecMakeFromData (sk_sp< SkData >, SkPngChunkReader *=nullptr)
 
static void Register (bool(*peek)(const void *, size_t), std::unique_ptr< SkCodec >(*make)(std::unique_ptr< SkStream >, SkCodec::Result *))
 

Protected Member Functions

SkISize onGetScaledDimensions (float desiredScale) const override
 
Result onGetPixels (const SkImageInfo &dstInfo, void *dst, size_t dstRowBytes, const Options &, int *) override
 
bool onQueryYUVAInfo (const SkYUVAPixmapInfo::SupportedDataTypes &, SkYUVAPixmapInfo *) const override
 
Result onGetYUVAPlanes (const SkYUVAPixmaps &yuvaPixmaps) override
 
SkEncodedImageFormat onGetEncodedFormat () const override
 
bool onRewind () override
 
bool onDimensionsSupported (const SkISize &) override
 
bool conversionSupported (const SkImageInfo &, bool, bool) override
 
bool onGetGainmapInfo (SkGainmapInfo *info, std::unique_ptr< SkStream > *gainmapImageStream) override
 
- Protected Member Functions inherited from SkCodec
const SkEncodedInfogetEncodedInfo () const
 
 SkCodec (SkEncodedInfo &&, XformFormat srcFormat, std::unique_ptr< SkStream >, SkEncodedOrigin=kTopLeft_SkEncodedOrigin)
 
void setSrcXformFormat (XformFormat pixelFormat)
 
XformFormat getSrcXformFormat () const
 
virtual bool onGetGainmapInfo (SkGainmapInfo *, std::unique_ptr< SkStream > *)
 
virtual SkISize onGetScaledDimensions (float) const
 
virtual bool onDimensionsSupported (const SkISize &)
 
virtual SkEncodedImageFormat onGetEncodedFormat () const =0
 
virtual Result onGetPixels (const SkImageInfo &info, void *pixels, size_t rowBytes, const Options &, int *rowsDecoded)=0
 
virtual bool onQueryYUVAInfo (const SkYUVAPixmapInfo::SupportedDataTypes &, SkYUVAPixmapInfo *) const
 
virtual Result onGetYUVAPlanes (const SkYUVAPixmaps &)
 
virtual bool onGetValidSubset (SkIRect *) const
 
bool rewindIfNeeded ()
 
virtual bool onRewind ()
 
SkStreamstream ()
 
virtual SkScanlineOrder onGetScanlineOrder () const
 
const SkImageInfodstInfo () const
 
const Optionsoptions () const
 
int currScanline () const
 
virtual int onOutputScanline (int inputScanline) const
 
virtual bool conversionSupported (const SkImageInfo &dst, bool srcIsOpaque, bool needsColorXform)
 
virtual bool usesColorXform () const
 
void applyColorXform (void *dst, const void *src, int count) const
 
bool colorXform () const
 
bool xformOnDecode () const
 
virtual int onGetFrameCount ()
 
virtual bool onGetFrameInfo (int, FrameInfo *) const
 
virtual int onGetRepetitionCount ()
 

Friends

class SkRawCodec
 

Additional Inherited Members

- Public Types inherited from SkCodec
enum  Result {
  kSuccess , kIncompleteInput , kErrorInInput , kInvalidConversion ,
  kInvalidScale , kInvalidParameters , kInvalidInput , kCouldNotRewind ,
  kInternalError , kUnimplemented
}
 
enum class  SelectionPolicy { kPreferStillImage , kPreferAnimation }
 
enum  ZeroInitialized { kYes_ZeroInitialized , kNo_ZeroInitialized }
 
enum  SkScanlineOrder { kTopDown_SkScanlineOrder , kBottomUp_SkScanlineOrder }
 
- Static Public Attributes inherited from SkCodec
static constexpr int kNoFrame = -1
 
static constexpr int kRepetitionCountInfinite = -1
 
- Protected Types inherited from SkCodec
using XformFormat = skcms_PixelFormat
 

Detailed Description

Definition at line 37 of file SkJpegCodec.h.

Constructor & Destructor Documentation

◆ ~SkJpegCodec()

SkJpegCodec::~SkJpegCodec ( )
overridedefault

Member Function Documentation

◆ conversionSupported()

bool SkJpegCodec::conversionSupported ( const SkImageInfo dst,
bool  srcIsOpaque,
bool  needsColorXform 
)
overrideprotectedvirtual

Return whether we can convert to dst.

Will be called for the appropriate frame, prior to initializing the colorXform.

Reimplemented from SkCodec.

Definition at line 283 of file SkJpegCodec.cpp.

284 {
285 SkASSERT(srcIsOpaque);
286
288 return false;
289 }
290
292 SkCodecPrintf("Warning: an opaque image should be decoded as opaque "
293 "- it is being decoded as non-opaque, which will draw slower\n");
294 }
295
296 J_COLOR_SPACE encodedColorType = fDecoderMgr->dinfo()->jpeg_color_space;
297
298 // Check for valid color types and set the output color space
299 switch (dstInfo.colorType()) {
301 fDecoderMgr->dinfo()->out_color_space = JCS_EXT_RGBA;
302 break;
304 if (needsColorXform) {
305 // Always using RGBA as the input format for color xforms makes the
306 // implementation a little simpler.
307 fDecoderMgr->dinfo()->out_color_space = JCS_EXT_RGBA;
308 } else {
309 fDecoderMgr->dinfo()->out_color_space = JCS_EXT_BGRA;
310 }
311 break;
313 if (needsColorXform) {
314 fDecoderMgr->dinfo()->out_color_space = JCS_EXT_RGBA;
315 } else {
316 fDecoderMgr->dinfo()->dither_mode = JDITHER_NONE;
317 fDecoderMgr->dinfo()->out_color_space = JCS_RGB565;
318 }
319 break;
321 if (JCS_GRAYSCALE != encodedColorType) {
322 return false;
323 }
324
325 if (needsColorXform) {
326 fDecoderMgr->dinfo()->out_color_space = JCS_EXT_RGBA;
327 } else {
328 fDecoderMgr->dinfo()->out_color_space = JCS_GRAYSCALE;
329 }
330 break;
334 SkASSERT(needsColorXform);
335 fDecoderMgr->dinfo()->out_color_space = JCS_EXT_RGBA;
336 break;
337 default:
338 return false;
339 }
340
341 // Check if we will decode to CMYK. libjpeg-turbo does not convert CMYK to RGBA, so
342 // we must do it ourselves.
343 if (JCS_CMYK == encodedColorType || JCS_YCCK == encodedColorType) {
344 fDecoderMgr->dinfo()->out_color_space = JCS_CMYK;
345 }
346
347 return true;
348}
@ kUnknown_SkAlphaType
uninitialized
Definition: SkAlphaType.h:27
@ kOpaque_SkAlphaType
pixel is opaque
Definition: SkAlphaType.h:28
#define SkASSERT(cond)
Definition: SkAssert.h:116
#define SkCodecPrintf(...)
Definition: SkCodecPriv.h:23
@ kBGRA_8888_SkColorType
pixel with 8 bits for blue, green, red, alpha; in 32-bit word
Definition: SkColorType.h:26
@ kRGBA_F16_SkColorType
pixel with half floats for red, green, blue, alpha;
Definition: SkColorType.h:38
@ kGray_8_SkColorType
pixel with grayscale level in 8-bit byte
Definition: SkColorType.h:35
@ kRGB_565_SkColorType
pixel with 5 bits red, 6 bits green, 5 bits blue, in 16-bit word
Definition: SkColorType.h:22
@ kBGRA_10101010_XR_SkColorType
pixel with 10 bits each for blue, green, red, alpha; in 64-bit word, extended range
Definition: SkColorType.h:32
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
Definition: SkColorType.h:24
@ kBGR_101010x_XR_SkColorType
pixel with 10 bits each for blue, green, red; in 32-bit word, extended range
Definition: SkColorType.h:31
const SkImageInfo & dstInfo() const
Definition: SkCodec.h:878
SkAlphaType alphaType() const
Definition: SkImageInfo.h:375
SkColorType colorType() const
Definition: SkImageInfo.h:373

◆ IsJpeg()

bool SkJpegCodec::IsJpeg ( const void *  buffer,
size_t  bytesRead 
)
static

Definition at line 56 of file SkJpegCodec.cpp.

56 {
57 return bytesRead >= sizeof(kJpegSig) && !memcmp(buffer, kJpegSig, sizeof(kJpegSig));
58}
static constexpr uint8_t kJpegSig[]
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
Definition: switches.h:126

◆ MakeFromStream()

std::unique_ptr< SkCodec > SkJpegCodec::MakeFromStream ( std::unique_ptr< SkStream stream,
Result result 
)
static

Definition at line 174 of file SkJpegCodec.cpp.

175 {
176 return SkJpegCodec::MakeFromStream(std::move(stream), result, nullptr);
177}
SkStream * stream()
Definition: SkCodec.h:865
static std::unique_ptr< SkCodec > MakeFromStream(std::unique_ptr< SkStream >, Result *)
GAsyncResult * result

◆ onDimensionsSupported()

bool SkJpegCodec::onDimensionsSupported ( const SkISize )
overrideprotectedvirtual

Subclasses should override if they support dimensions other than the srcInfo's.

Reimplemented from SkCodec.

Definition at line 354 of file SkJpegCodec.cpp.

354 {
355 skjpeg_error_mgr::AutoPushJmpBuf jmp(fDecoderMgr->errorMgr());
356 if (setjmp(jmp)) {
357 return fDecoderMgr->returnFalse("onDimensionsSupported");
358 }
359
360 const unsigned int dstWidth = size.width();
361 const unsigned int dstHeight = size.height();
362
363 // Set up a fake decompress struct in order to use libjpeg to calculate output dimensions
364 // FIXME: Why is this necessary?
365 jpeg_decompress_struct dinfo;
366 sk_bzero(&dinfo, sizeof(dinfo));
367 dinfo.image_width = this->dimensions().width();
368 dinfo.image_height = this->dimensions().height();
369 dinfo.global_state = fReadyState;
370
371 // libjpeg-turbo can scale to 1/8, 1/4, 3/8, 1/2, 5/8, 3/4, 7/8, and 1/1
372 unsigned int num = 8;
373 const unsigned int denom = 8;
374 calc_output_dimensions(&dinfo, num, denom);
375 while (dinfo.output_width != dstWidth || dinfo.output_height != dstHeight) {
376
377 // Return a failure if we have tried all of the possible scales
378 if (1 == num || dstWidth > dinfo.output_width || dstHeight > dinfo.output_height) {
379 return false;
380 }
381
382 // Try the next scale
383 num -= 1;
384 calc_output_dimensions(&dinfo, num, denom);
385 }
386
387 fDecoderMgr->dinfo()->scale_num = num;
388 fDecoderMgr->dinfo()->scale_denom = denom;
389 return true;
390}
sk_bzero(glyphs, sizeof(glyphs))
void calc_output_dimensions(jpeg_decompress_struct *dinfo, unsigned int num, unsigned int denom)
SkISize dimensions() const
Definition: SkCodec.h:230
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
constexpr int32_t width() const
Definition: SkSize.h:36
constexpr int32_t height() const
Definition: SkSize.h:37

◆ onGetEncodedFormat()

SkEncodedImageFormat SkJpegCodec::onGetEncodedFormat ( ) const
inlineoverrideprotectedvirtual

Implements SkCodec.

Definition at line 67 of file SkJpegCodec.h.

◆ onGetGainmapInfo()

bool SkJpegCodec::onGetGainmapInfo ( SkGainmapInfo info,
std::unique_ptr< SkStream > *  gainmapImageStream 
)
overrideprotectedvirtual

Reimplemented from SkCodec.

Definition at line 908 of file SkJpegCodec.cpp.

909 {
910#ifdef SK_CODEC_DECODES_JPEG_GAINMAPS
911 sk_sp<SkData> gainmap_data;
912 SkGainmapInfo gainmap_info;
913
914 auto metadataDecoder =
915 std::make_unique<SkJpegMetadataDecoderImpl>(get_sk_marker_list(fDecoderMgr->dinfo()));
916 if (!metadataDecoder->findGainmapImage(
917 fDecoderMgr->getSourceMgr(), gainmap_data, gainmap_info)) {
918 return false;
919 }
920
921 *info = gainmap_info;
922 *gainmapImageStream = SkMemoryStream::Make(gainmap_data);
923 return true;
924#else
925 return false;
926#endif // SK_CODEC_DECODES_JPEG_GAINMAPS
927}
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
SkJpegMarkerList get_sk_marker_list(jpeg_decompress_struct *dinfo)
Definition: SkJpegCodec.cpp:60
static std::unique_ptr< SkMemoryStream > Make(sk_sp< SkData > data)
Definition: SkStream.cpp:314

◆ onGetPixels()

SkCodec::Result SkJpegCodec::onGetPixels ( const SkImageInfo info,
void *  pixels,
size_t  rowBytes,
const Options ,
int rowsDecoded 
)
overrideprotectedvirtual
Parameters
rowsDecodedWhen the encoded image stream is incomplete, this function will return kIncompleteInput and rowsDecoded will be set to the number of scanlines that were successfully decoded. This will allow getPixels() to fill the uninitialized memory.

Implements SkCodec.

Definition at line 472 of file SkJpegCodec.cpp.

475 {
476 if (options.fSubset) {
477 // Subsets are not supported.
478 return kUnimplemented;
479 }
480
481 // Get a pointer to the decompress info since we will use it quite frequently
482 jpeg_decompress_struct* dinfo = fDecoderMgr->dinfo();
483
484 // Set the jump location for libjpeg errors
485 skjpeg_error_mgr::AutoPushJmpBuf jmp(fDecoderMgr->errorMgr());
486 if (setjmp(jmp)) {
487 return fDecoderMgr->returnFailure("setjmp", kInvalidInput);
488 }
489
490 if (!jpeg_start_decompress(dinfo)) {
491 return fDecoderMgr->returnFailure("startDecompress", kInvalidInput);
492 }
493
494 // The recommended output buffer height should always be 1 in high quality modes.
495 // If it's not, we want to know because it means our strategy is not optimal.
496 SkASSERT(1 == dinfo->rec_outbuf_height);
497
498 if (needs_swizzler_to_convert_from_cmyk(dinfo->out_color_space,
499 this->getEncodedInfo().profile(), this->colorXform())) {
500 this->initializeSwizzler(dstInfo, options, true);
501 }
502
503 if (!this->allocateStorage(dstInfo)) {
504 return kInternalError;
505 }
506
507 int rows = this->readRows(dstInfo, dst, dstRowBytes, dstInfo.height(), options);
508 if (rows < dstInfo.height()) {
509 *rowsDecoded = rows;
510 return fDecoderMgr->returnFailure("Incomplete image data", kIncompleteInput);
511 }
512
513 return kSuccess;
514}
static bool needs_swizzler_to_convert_from_cmyk(J_COLOR_SPACE jpegColorType, const skcms_ICCProfile *srcProfile, bool hasColorSpaceXform)
@ kIncompleteInput
Definition: SkCodec.h:84
@ kInvalidInput
Definition: SkCodec.h:109
@ kInternalError
Definition: SkCodec.h:118
@ kUnimplemented
Definition: SkCodec.h:123
@ kSuccess
Definition: SkCodec.h:80
const Options & options() const
Definition: SkCodec.h:880
dst
Definition: cp.py:12
const SkIRect * fSubset
Definition: SkCodec.h:347
int height() const
Definition: SkImageInfo.h:371

◆ onGetScaledDimensions()

SkISize SkJpegCodec::onGetScaledDimensions ( float  desiredScale) const
overrideprotectedvirtual

Reimplemented from SkCodec.

Definition at line 232 of file SkJpegCodec.cpp.

232 {
233 // libjpeg-turbo supports scaling by 1/8, 1/4, 3/8, 1/2, 5/8, 3/4, 7/8, and 1/1, so we will
234 // support these as well
235 unsigned int num;
236 unsigned int denom = 8;
237 if (desiredScale >= 0.9375) {
238 num = 8;
239 } else if (desiredScale >= 0.8125) {
240 num = 7;
241 } else if (desiredScale >= 0.6875f) {
242 num = 6;
243 } else if (desiredScale >= 0.5625f) {
244 num = 5;
245 } else if (desiredScale >= 0.4375f) {
246 num = 4;
247 } else if (desiredScale >= 0.3125f) {
248 num = 3;
249 } else if (desiredScale >= 0.1875f) {
250 num = 2;
251 } else {
252 num = 1;
253 }
254
255 // Set up a fake decompress struct in order to use libjpeg to calculate output dimensions
256 jpeg_decompress_struct dinfo;
257 sk_bzero(&dinfo, sizeof(dinfo));
258 dinfo.image_width = this->dimensions().width();
259 dinfo.image_height = this->dimensions().height();
260 dinfo.global_state = fReadyState;
261 calc_output_dimensions(&dinfo, num, denom);
262
263 // Return the calculated output dimensions for the given scale
264 return SkISize::Make(dinfo.output_width, dinfo.output_height);
265}
static constexpr SkISize Make(int32_t w, int32_t h)
Definition: SkSize.h:20

◆ onGetYUVAPlanes()

SkCodec::Result SkJpegCodec::onGetYUVAPlanes ( const SkYUVAPixmaps yuvaPixmaps)
overrideprotectedvirtual

Reimplemented from SkCodec.

Definition at line 792 of file SkJpegCodec.cpp.

792 {
793 // Get a pointer to the decompress info since we will use it quite frequently
794 jpeg_decompress_struct* dinfo = fDecoderMgr->dinfo();
795 if (!is_yuv_supported(dinfo, *this, nullptr, nullptr)) {
796 return fDecoderMgr->returnFailure("onGetYUVAPlanes", kInvalidInput);
797 }
798 // Set the jump location for libjpeg errors
799 skjpeg_error_mgr::AutoPushJmpBuf jmp(fDecoderMgr->errorMgr());
800 if (setjmp(jmp)) {
801 return fDecoderMgr->returnFailure("setjmp", kInvalidInput);
802 }
803
804 dinfo->raw_data_out = TRUE;
805 if (!jpeg_start_decompress(dinfo)) {
806 return fDecoderMgr->returnFailure("startDecompress", kInvalidInput);
807 }
808
809 const std::array<SkPixmap, SkYUVAPixmaps::kMaxPlanes>& planes = yuvaPixmaps.planes();
810
811#ifdef SK_DEBUG
812 {
813 // A previous implementation claims that the return value of is_yuv_supported()
814 // may change after calling jpeg_start_decompress(). It looks to me like this
815 // was caused by a bug in the old code, but we'll be safe and check here.
816 // Also check that pixmap properties agree with expectations.
818 SkASSERT(is_yuv_supported(dinfo, *this, nullptr, &info));
819 SkASSERT(info.yuvaInfo() == yuvaPixmaps.yuvaInfo());
820 for (int i = 0; i < info.numPlanes(); ++i) {
822 SkASSERT(info.planeInfo(i) == planes[i].info());
823 }
824 }
825#endif
826
827 // Build a JSAMPIMAGE to handle output from libjpeg-turbo. A JSAMPIMAGE has
828 // a 2-D array of pixels for each of the components (Y, U, V) in the image.
829 // Cheat Sheet:
830 // JSAMPIMAGE == JSAMPLEARRAY* == JSAMPROW** == JSAMPLE***
831 JSAMPARRAY yuv[3];
832
833 // Set aside enough space for pointers to rows of Y, U, and V.
834 JSAMPROW rowptrs[2 * DCTSIZE + DCTSIZE + DCTSIZE];
835 yuv[0] = &rowptrs[0]; // Y rows (DCTSIZE or 2 * DCTSIZE)
836 yuv[1] = &rowptrs[2 * DCTSIZE]; // U rows (DCTSIZE)
837 yuv[2] = &rowptrs[3 * DCTSIZE]; // V rows (DCTSIZE)
838
839 // Initialize rowptrs.
840 int numYRowsPerBlock = DCTSIZE * dinfo->comp_info[0].v_samp_factor;
841 static_assert(sizeof(JSAMPLE) == 1);
842 for (int i = 0; i < numYRowsPerBlock; i++) {
843 rowptrs[i] = static_cast<JSAMPLE*>(planes[0].writable_addr()) + i* planes[0].rowBytes();
844 }
845 for (int i = 0; i < DCTSIZE; i++) {
846 rowptrs[i + 2 * DCTSIZE] =
847 static_cast<JSAMPLE*>(planes[1].writable_addr()) + i* planes[1].rowBytes();
848 rowptrs[i + 3 * DCTSIZE] =
849 static_cast<JSAMPLE*>(planes[2].writable_addr()) + i* planes[2].rowBytes();
850 }
851
852 // After each loop iteration, we will increment pointers to Y, U, and V.
853 size_t blockIncrementY = numYRowsPerBlock * planes[0].rowBytes();
854 size_t blockIncrementU = DCTSIZE * planes[1].rowBytes();
855 size_t blockIncrementV = DCTSIZE * planes[2].rowBytes();
856
857 uint32_t numRowsPerBlock = numYRowsPerBlock;
858
859 // We intentionally round down here, as this first loop will only handle
860 // full block rows. As a special case at the end, we will handle any
861 // remaining rows that do not make up a full block.
862 const int numIters = dinfo->output_height / numRowsPerBlock;
863 for (int i = 0; i < numIters; i++) {
864 JDIMENSION linesRead = jpeg_read_raw_data(dinfo, yuv, numRowsPerBlock);
865 if (linesRead < numRowsPerBlock) {
866 // FIXME: Handle incomplete YUV decodes without signalling an error.
867 return kInvalidInput;
868 }
869
870 // Update rowptrs.
871 for (int j = 0; j < numYRowsPerBlock; j++) {
872 rowptrs[j] += blockIncrementY;
873 }
874 for (int j = 0; j < DCTSIZE; j++) {
875 rowptrs[j + 2 * DCTSIZE] += blockIncrementU;
876 rowptrs[j + 3 * DCTSIZE] += blockIncrementV;
877 }
878 }
879
880 uint32_t remainingRows = dinfo->output_height - dinfo->output_scanline;
881 SkASSERT(remainingRows == dinfo->output_height % numRowsPerBlock);
882 SkASSERT(dinfo->output_scanline == numIters * numRowsPerBlock);
883 if (remainingRows > 0) {
884 // libjpeg-turbo needs memory to be padded by the block sizes. We will fulfill
885 // this requirement using an extra row buffer.
886 // FIXME: Should SkCodec have an extra memory buffer that can be shared among
887 // all of the implementations that use temporary/garbage memory?
888 AutoTMalloc<JSAMPLE> extraRow(planes[0].rowBytes());
889 for (int i = remainingRows; i < numYRowsPerBlock; i++) {
890 rowptrs[i] = extraRow.get();
891 }
892 int remainingUVRows = dinfo->comp_info[1].downsampled_height - DCTSIZE * numIters;
893 for (int i = remainingUVRows; i < DCTSIZE; i++) {
894 rowptrs[i + 2 * DCTSIZE] = extraRow.get();
895 rowptrs[i + 3 * DCTSIZE] = extraRow.get();
896 }
897
898 JDIMENSION linesRead = jpeg_read_raw_data(dinfo, yuv, numRowsPerBlock);
899 if (linesRead < remainingRows) {
900 // FIXME: Handle incomplete YUV decodes without signalling an error.
901 return kInvalidInput;
902 }
903 }
904
905 return kSuccess;
906}
@ kAlpha_8_SkColorType
pixel with alpha in 8-bit byte
Definition: SkColorType.h:21
static SkColorType colorType(AImageDecoder *decoder, const AImageDecoderHeaderInfo *headerInfo)
static bool is_yuv_supported(const jpeg_decompress_struct *dinfo, const SkJpegCodec &codec, const SkYUVAPixmapInfo::SupportedDataTypes *supportedDataTypes, SkYUVAPixmapInfo *yuvaPixmapInfo)
const SkYUVAInfo & yuvaInfo() const
const std::array< SkPixmap, kMaxPlanes > & planes() const

◆ onQueryYUVAInfo()

bool SkJpegCodec::onQueryYUVAInfo ( const SkYUVAPixmapInfo::SupportedDataTypes supportedDataTypes,
SkYUVAPixmapInfo yuvaPixmapInfo 
) const
overrideprotectedvirtual

Reimplemented from SkCodec.

Definition at line 786 of file SkJpegCodec.cpp.

787 {
788 jpeg_decompress_struct* dinfo = fDecoderMgr->dinfo();
789 return is_yuv_supported(dinfo, *this, &supportedDataTypes, yuvaPixmapInfo);
790}

◆ onRewind()

bool SkJpegCodec::onRewind ( )
overrideprotectedvirtual

Called by rewindIfNeeded, if the stream needed to be rewound.

Subclasses should do any set up needed after a rewind.

Reimplemented from SkCodec.

Definition at line 267 of file SkJpegCodec.cpp.

267 {
268 JpegDecoderMgr* decoderMgr = nullptr;
269 if (kSuccess != ReadHeader(this->stream(), nullptr, &decoderMgr, nullptr)) {
270 return fDecoderMgr->returnFalse("onRewind");
271 }
272 SkASSERT(nullptr != decoderMgr);
273 fDecoderMgr.reset(decoderMgr);
274
275 fSwizzler.reset(nullptr);
276 fSwizzleSrcRow = nullptr;
277 fColorXformSrcRow = nullptr;
278 fStorage.reset();
279
280 return true;
281}
T * reset(size_t count=0)
Definition: SkTemplates.h:296

Friends And Related Function Documentation

◆ SkRawCodec

friend class SkRawCodec
friend

Definition at line 161 of file SkJpegCodec.h.


The documentation for this class was generated from the following files: