Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Public Member Functions | Static Public Member Functions | Protected Member Functions | Private 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 onGetValidSubset (SkIRect *) const
 
bool rewindIfNeeded ()
 
SkStreamstream ()
 
virtual SkScanlineOrder onGetScanlineOrder () const
 
const SkImageInfodstInfo () const
 
const Optionsoptions () const
 
int currScanline () const
 
virtual int onOutputScanline (int inputScanline) const
 
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 ()
 

Private Member Functions

SkSamplergetSampler (bool createIfNecessary) override
 
Result onStartScanlineDecode (const SkImageInfo &dstInfo, const Options &options) override
 
int onGetScanlines (void *dst, int count, size_t rowBytes) override
 
bool onSkipScanlines (int count) override
 

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 458 of file SkJpegCodec.cpp.

459 {
460 SkASSERT(srcIsOpaque);
461
463 return false;
464 }
465
467 SkCodecPrintf("Warning: an opaque image should be decoded as opaque "
468 "- it is being decoded as non-opaque, which will draw slower\n");
469 }
470
471 J_COLOR_SPACE encodedColorType = fDecoderMgr->dinfo()->jpeg_color_space;
472
473 // Check for valid color types and set the output color space
474 switch (dstInfo.colorType()) {
476 fDecoderMgr->dinfo()->out_color_space = JCS_EXT_RGBA;
477 break;
479 if (needsColorXform) {
480 // Always using RGBA as the input format for color xforms makes the
481 // implementation a little simpler.
482 fDecoderMgr->dinfo()->out_color_space = JCS_EXT_RGBA;
483 } else {
484 fDecoderMgr->dinfo()->out_color_space = JCS_EXT_BGRA;
485 }
486 break;
488 if (needsColorXform) {
489 fDecoderMgr->dinfo()->out_color_space = JCS_EXT_RGBA;
490 } else {
491 fDecoderMgr->dinfo()->dither_mode = JDITHER_NONE;
492 fDecoderMgr->dinfo()->out_color_space = JCS_RGB565;
493 }
494 break;
496 if (JCS_GRAYSCALE != encodedColorType) {
497 return false;
498 }
499
500 if (needsColorXform) {
501 fDecoderMgr->dinfo()->out_color_space = JCS_EXT_RGBA;
502 } else {
503 fDecoderMgr->dinfo()->out_color_space = JCS_GRAYSCALE;
504 }
505 break;
509 SkASSERT(needsColorXform);
510 fDecoderMgr->dinfo()->out_color_space = JCS_EXT_RGBA;
511 break;
512 default:
513 return false;
514 }
515
516 // Check if we will decode to CMYK. libjpeg-turbo does not convert CMYK to RGBA, so
517 // we must do it ourselves.
518 if (JCS_CMYK == encodedColorType || JCS_YCCK == encodedColorType) {
519 fDecoderMgr->dinfo()->out_color_space = JCS_CMYK;
520 }
521
522 return true;
523}
@ 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
SkColorType colorType() const

◆ getSampler()

SkSampler * SkJpegCodec::getSampler ( bool  )
overrideprivatevirtual

Return an object which will allow forcing scanline decodes to sample in X.

May create a sampler, if one is not currently being used. Otherwise, does not affect ownership.

Only valid during scanline decoding or incremental decoding.

Reimplemented from SkCodec.

Definition at line 766 of file SkJpegCodec.cpp.

766 {
767 if (!createIfNecessary || fSwizzler) {
768 SkASSERT(!fSwizzler || (fSwizzleSrcRow && fStorage.get() == fSwizzleSrcRow));
769 return fSwizzler.get();
770 }
771
772 bool needsCMYKToRGB = needs_swizzler_to_convert_from_cmyk(
773 fDecoderMgr->dinfo()->out_color_space, this->getEncodedInfo().profile(),
774 this->colorXform());
775 this->initializeSwizzler(this->dstInfo(), this->options(), needsCMYKToRGB);
776 if (!this->allocateStorage(this->dstInfo())) {
777 return nullptr;
778 }
779 return fSwizzler.get();
780}
static bool needs_swizzler_to_convert_from_cmyk(J_COLOR_SPACE jpegColorType, const skcms_ICCProfile *srcProfile, bool hasColorSpaceXform)
const Options & options() const
Definition SkCodec.h:880

◆ IsJpeg()

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

Definition at line 61 of file SkJpegCodec.cpp.

61 {
62 return bytesRead >= sizeof(kJpegSig) && !memcmp(buffer, kJpegSig, sizeof(kJpegSig));
63}
static constexpr uint8_t kJpegSig[]
static const uint8_t buffer[]

◆ MakeFromStream()

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

Definition at line 349 of file SkJpegCodec.cpp.

350 {
351 return SkJpegCodec::MakeFromStream(std::move(stream), result, nullptr);
352}
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 529 of file SkJpegCodec.cpp.

529 {
530 skjpeg_error_mgr::AutoPushJmpBuf jmp(fDecoderMgr->errorMgr());
531 if (setjmp(jmp)) {
532 return fDecoderMgr->returnFalse("onDimensionsSupported");
533 }
534
535 const unsigned int dstWidth = size.width();
536 const unsigned int dstHeight = size.height();
537
538 // Set up a fake decompress struct in order to use libjpeg to calculate output dimensions
539 // FIXME: Why is this necessary?
540 jpeg_decompress_struct dinfo;
541 sk_bzero(&dinfo, sizeof(dinfo));
542 dinfo.image_width = this->dimensions().width();
543 dinfo.image_height = this->dimensions().height();
544 dinfo.global_state = fReadyState;
545
546 // libjpeg-turbo can scale to 1/8, 1/4, 3/8, 1/2, 5/8, 3/4, 7/8, and 1/1
547 unsigned int num = 8;
548 const unsigned int denom = 8;
549 calc_output_dimensions(&dinfo, num, denom);
550 while (dinfo.output_width != dstWidth || dinfo.output_height != dstHeight) {
551
552 // Return a failure if we have tried all of the possible scales
553 if (1 == num || dstWidth > dinfo.output_width || dstHeight > dinfo.output_height) {
554 return false;
555 }
556
557 // Try the next scale
558 num -= 1;
559 calc_output_dimensions(&dinfo, num, denom);
560 }
561
562 fDecoderMgr->dinfo()->scale_num = num;
563 fDecoderMgr->dinfo()->scale_denom = denom;
564 return true;
565}
void calc_output_dimensions(jpeg_decompress_struct *dinfo, unsigned int num, unsigned int denom)
static void sk_bzero(void *buffer, size_t size)
Definition SkMalloc.h:105
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 1312 of file SkJpegCodec.cpp.

1313 {
1314 return false;
1315}

◆ 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 647 of file SkJpegCodec.cpp.

650 {
651 if (options.fSubset) {
652 // Subsets are not supported.
653 return kUnimplemented;
654 }
655
656 // Get a pointer to the decompress info since we will use it quite frequently
657 jpeg_decompress_struct* dinfo = fDecoderMgr->dinfo();
658
659 // Set the jump location for libjpeg errors
660 skjpeg_error_mgr::AutoPushJmpBuf jmp(fDecoderMgr->errorMgr());
661 if (setjmp(jmp)) {
662 return fDecoderMgr->returnFailure("setjmp", kInvalidInput);
663 }
664
665 if (!jpeg_start_decompress(dinfo)) {
666 return fDecoderMgr->returnFailure("startDecompress", kInvalidInput);
667 }
668
669 // The recommended output buffer height should always be 1 in high quality modes.
670 // If it's not, we want to know because it means our strategy is not optimal.
671 SkASSERT(1 == dinfo->rec_outbuf_height);
672
673 if (needs_swizzler_to_convert_from_cmyk(dinfo->out_color_space,
674 this->getEncodedInfo().profile(), this->colorXform())) {
675 this->initializeSwizzler(dstInfo, options, true);
676 }
677
678 if (!this->allocateStorage(dstInfo)) {
679 return kInternalError;
680 }
681
682 int rows = this->readRows(dstInfo, dst, dstRowBytes, dstInfo.height(), options);
683 if (rows < dstInfo.height()) {
684 *rowsDecoded = rows;
685 return fDecoderMgr->returnFailure("Incomplete image data", kIncompleteInput);
686 }
687
688 return kSuccess;
689}
@ 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 SkIRect * fSubset
Definition SkCodec.h:347
int height() const

◆ onGetScaledDimensions()

SkISize SkJpegCodec::onGetScaledDimensions ( float  desiredScale) const
overrideprotectedvirtual

Reimplemented from SkCodec.

Definition at line 407 of file SkJpegCodec.cpp.

407 {
408 // 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
409 // support these as well
410 unsigned int num;
411 unsigned int denom = 8;
412 if (desiredScale >= 0.9375) {
413 num = 8;
414 } else if (desiredScale >= 0.8125) {
415 num = 7;
416 } else if (desiredScale >= 0.6875f) {
417 num = 6;
418 } else if (desiredScale >= 0.5625f) {
419 num = 5;
420 } else if (desiredScale >= 0.4375f) {
421 num = 4;
422 } else if (desiredScale >= 0.3125f) {
423 num = 3;
424 } else if (desiredScale >= 0.1875f) {
425 num = 2;
426 } else {
427 num = 1;
428 }
429
430 // Set up a fake decompress struct in order to use libjpeg to calculate output dimensions
431 jpeg_decompress_struct dinfo;
432 sk_bzero(&dinfo, sizeof(dinfo));
433 dinfo.image_width = this->dimensions().width();
434 dinfo.image_height = this->dimensions().height();
435 dinfo.global_state = fReadyState;
436 calc_output_dimensions(&dinfo, num, denom);
437
438 // Return the calculated output dimensions for the given scale
439 return SkISize::Make(dinfo.output_width, dinfo.output_height);
440}
static constexpr SkISize Make(int32_t w, int32_t h)
Definition SkSize.h:20

◆ onGetScanlines()

int SkJpegCodec::onGetScanlines ( void *  dst,
int  count,
size_t  rowBytes 
)
overrideprivatevirtual

Reimplemented from SkCodec.

Definition at line 848 of file SkJpegCodec.cpp.

848 {
849 int rows = this->readRows(this->dstInfo(), dst, dstRowBytes, count, this->options());
850 if (rows < count) {
851 // This allows us to skip calling jpeg_finish_decompress().
852 fDecoderMgr->dinfo()->output_scanline = this->dstInfo().height();
853 }
854
855 return rows;
856}
int count

◆ onGetYUVAPlanes()

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

Reimplemented from SkCodec.

Definition at line 967 of file SkJpegCodec.cpp.

967 {
968 // Get a pointer to the decompress info since we will use it quite frequently
969 jpeg_decompress_struct* dinfo = fDecoderMgr->dinfo();
970 if (!is_yuv_supported(dinfo, *this, nullptr, nullptr)) {
971 return fDecoderMgr->returnFailure("onGetYUVAPlanes", kInvalidInput);
972 }
973 // Set the jump location for libjpeg errors
974 skjpeg_error_mgr::AutoPushJmpBuf jmp(fDecoderMgr->errorMgr());
975 if (setjmp(jmp)) {
976 return fDecoderMgr->returnFailure("setjmp", kInvalidInput);
977 }
978
979 dinfo->raw_data_out = TRUE;
980 if (!jpeg_start_decompress(dinfo)) {
981 return fDecoderMgr->returnFailure("startDecompress", kInvalidInput);
982 }
983
984 const std::array<SkPixmap, SkYUVAPixmaps::kMaxPlanes>& planes = yuvaPixmaps.planes();
985
986#ifdef SK_DEBUG
987 {
988 // A previous implementation claims that the return value of is_yuv_supported()
989 // may change after calling jpeg_start_decompress(). It looks to me like this
990 // was caused by a bug in the old code, but we'll be safe and check here.
991 // Also check that pixmap properties agree with expectations.
993 SkASSERT(is_yuv_supported(dinfo, *this, nullptr, &info));
994 SkASSERT(info.yuvaInfo() == yuvaPixmaps.yuvaInfo());
995 for (int i = 0; i < info.numPlanes(); ++i) {
997 SkASSERT(info.planeInfo(i) == planes[i].info());
998 }
999 }
1000#endif
1001
1002 // Build a JSAMPIMAGE to handle output from libjpeg-turbo. A JSAMPIMAGE has
1003 // a 2-D array of pixels for each of the components (Y, U, V) in the image.
1004 // Cheat Sheet:
1005 // JSAMPIMAGE == JSAMPLEARRAY* == JSAMPROW** == JSAMPLE***
1006 JSAMPARRAY yuv[3];
1007
1008 // Set aside enough space for pointers to rows of Y, U, and V.
1009 JSAMPROW rowptrs[2 * DCTSIZE + DCTSIZE + DCTSIZE];
1010 yuv[0] = &rowptrs[0]; // Y rows (DCTSIZE or 2 * DCTSIZE)
1011 yuv[1] = &rowptrs[2 * DCTSIZE]; // U rows (DCTSIZE)
1012 yuv[2] = &rowptrs[3 * DCTSIZE]; // V rows (DCTSIZE)
1013
1014 // Initialize rowptrs.
1015 int numYRowsPerBlock = DCTSIZE * dinfo->comp_info[0].v_samp_factor;
1016 static_assert(sizeof(JSAMPLE) == 1);
1017 for (int i = 0; i < numYRowsPerBlock; i++) {
1018 rowptrs[i] = static_cast<JSAMPLE*>(planes[0].writable_addr()) + i* planes[0].rowBytes();
1019 }
1020 for (int i = 0; i < DCTSIZE; i++) {
1021 rowptrs[i + 2 * DCTSIZE] =
1022 static_cast<JSAMPLE*>(planes[1].writable_addr()) + i* planes[1].rowBytes();
1023 rowptrs[i + 3 * DCTSIZE] =
1024 static_cast<JSAMPLE*>(planes[2].writable_addr()) + i* planes[2].rowBytes();
1025 }
1026
1027 // After each loop iteration, we will increment pointers to Y, U, and V.
1028 size_t blockIncrementY = numYRowsPerBlock * planes[0].rowBytes();
1029 size_t blockIncrementU = DCTSIZE * planes[1].rowBytes();
1030 size_t blockIncrementV = DCTSIZE * planes[2].rowBytes();
1031
1032 uint32_t numRowsPerBlock = numYRowsPerBlock;
1033
1034 // We intentionally round down here, as this first loop will only handle
1035 // full block rows. As a special case at the end, we will handle any
1036 // remaining rows that do not make up a full block.
1037 const int numIters = dinfo->output_height / numRowsPerBlock;
1038 for (int i = 0; i < numIters; i++) {
1039 JDIMENSION linesRead = jpeg_read_raw_data(dinfo, yuv, numRowsPerBlock);
1040 if (linesRead < numRowsPerBlock) {
1041 // FIXME: Handle incomplete YUV decodes without signalling an error.
1042 return kInvalidInput;
1043 }
1044
1045 // Update rowptrs.
1046 for (int j = 0; j < numYRowsPerBlock; j++) {
1047 rowptrs[j] += blockIncrementY;
1048 }
1049 for (int j = 0; j < DCTSIZE; j++) {
1050 rowptrs[j + 2 * DCTSIZE] += blockIncrementU;
1051 rowptrs[j + 3 * DCTSIZE] += blockIncrementV;
1052 }
1053 }
1054
1055 uint32_t remainingRows = dinfo->output_height - dinfo->output_scanline;
1056 SkASSERT(remainingRows == dinfo->output_height % numRowsPerBlock);
1057 SkASSERT(dinfo->output_scanline == numIters * numRowsPerBlock);
1058 if (remainingRows > 0) {
1059 // libjpeg-turbo needs memory to be padded by the block sizes. We will fulfill
1060 // this requirement using an extra row buffer.
1061 // FIXME: Should SkCodec have an extra memory buffer that can be shared among
1062 // all of the implementations that use temporary/garbage memory?
1063 AutoTMalloc<JSAMPLE> extraRow(planes[0].rowBytes());
1064 for (int i = remainingRows; i < numYRowsPerBlock; i++) {
1065 rowptrs[i] = extraRow.get();
1066 }
1067 int remainingUVRows = dinfo->comp_info[1].downsampled_height - DCTSIZE * numIters;
1068 for (int i = remainingUVRows; i < DCTSIZE; i++) {
1069 rowptrs[i + 2 * DCTSIZE] = extraRow.get();
1070 rowptrs[i + 3 * DCTSIZE] = extraRow.get();
1071 }
1072
1073 JDIMENSION linesRead = jpeg_read_raw_data(dinfo, yuv, numRowsPerBlock);
1074 if (linesRead < remainingRows) {
1075 // FIXME: Handle incomplete YUV decodes without signalling an error.
1076 return kInvalidInput;
1077 }
1078 }
1079
1080 return kSuccess;
1081}
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition DM.cpp:213
@ 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 961 of file SkJpegCodec.cpp.

962 {
963 jpeg_decompress_struct* dinfo = fDecoderMgr->dinfo();
964 return is_yuv_supported(dinfo, *this, &supportedDataTypes, yuvaPixmapInfo);
965}

◆ 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 442 of file SkJpegCodec.cpp.

442 {
443 JpegDecoderMgr* decoderMgr = nullptr;
444 if (kSuccess != ReadHeader(this->stream(), nullptr, &decoderMgr, nullptr)) {
445 return fDecoderMgr->returnFalse("onRewind");
446 }
447 SkASSERT(nullptr != decoderMgr);
448 fDecoderMgr.reset(decoderMgr);
449
450 fSwizzler.reset(nullptr);
451 fSwizzleSrcRow = nullptr;
452 fColorXformSrcRow = nullptr;
453 fStorage.reset();
454
455 return true;
456}
T * reset(size_t count=0)

◆ onSkipScanlines()

bool SkJpegCodec::onSkipScanlines ( int  count)
overrideprivatevirtual

Reimplemented from SkCodec.

Definition at line 858 of file SkJpegCodec.cpp.

858 {
859 // Set the jump location for libjpeg errors
860 skjpeg_error_mgr::AutoPushJmpBuf jmp(fDecoderMgr->errorMgr());
861 if (setjmp(jmp)) {
862 return fDecoderMgr->returnFalse("onSkipScanlines");
863 }
864
865 return (uint32_t) count == jpeg_skip_scanlines(fDecoderMgr->dinfo(), count);
866}

◆ onStartScanlineDecode()

SkCodec::Result SkJpegCodec::onStartScanlineDecode ( const SkImageInfo dstInfo,
const Options options 
)
overrideprivatevirtual

Reimplemented from SkCodec.

Definition at line 782 of file SkJpegCodec.cpp.

783 {
784 // Set the jump location for libjpeg errors
785 skjpeg_error_mgr::AutoPushJmpBuf jmp(fDecoderMgr->errorMgr());
786 if (setjmp(jmp)) {
787 SkCodecPrintf("setjmp: Error from libjpeg\n");
788 return kInvalidInput;
789 }
790
791 if (!jpeg_start_decompress(fDecoderMgr->dinfo())) {
792 SkCodecPrintf("start decompress failed\n");
793 return kInvalidInput;
794 }
795
796 bool needsCMYKToRGB = needs_swizzler_to_convert_from_cmyk(
797 fDecoderMgr->dinfo()->out_color_space, this->getEncodedInfo().profile(),
798 this->colorXform());
799 if (options.fSubset) {
800 uint32_t startX = options.fSubset->x();
801 uint32_t width = options.fSubset->width();
802
803 // libjpeg-turbo may need to align startX to a multiple of the IDCT
804 // block size. If this is the case, it will decrease the value of
805 // startX to the appropriate alignment and also increase the value
806 // of width so that the right edge of the requested subset remains
807 // the same.
808 jpeg_crop_scanline(fDecoderMgr->dinfo(), &startX, &width);
809
810 SkASSERT(startX <= (uint32_t) options.fSubset->x());
811 SkASSERT(width >= (uint32_t) options.fSubset->width());
812 SkASSERT(startX + width >= (uint32_t) options.fSubset->right());
813
814 // Instruct the swizzler (if it is necessary) to further subset the
815 // output provided by libjpeg-turbo.
816 //
817 // We set this here (rather than in the if statement below), so that
818 // if (1) we don't need a swizzler for the subset, and (2) we need a
819 // swizzler for CMYK, the swizzler will still use the proper subset
820 // dimensions.
821 //
822 // Note that the swizzler will ignore the y and height parameters of
823 // the subset. Since the scanline decoder (and the swizzler) handle
824 // one row at a time, only the subsetting in the x-dimension matters.
825 fSwizzlerSubset.setXYWH(options.fSubset->x() - startX, 0,
827
828 // We will need a swizzler if libjpeg-turbo cannot provide the exact
829 // subset that we request.
830 if (startX != (uint32_t) options.fSubset->x() ||
831 width != (uint32_t) options.fSubset->width()) {
832 this->initializeSwizzler(dstInfo, options, needsCMYKToRGB);
833 }
834 }
835
836 // Make sure we have a swizzler if we are converting from CMYK.
837 if (!fSwizzler && needsCMYKToRGB) {
838 this->initializeSwizzler(dstInfo, options, true);
839 }
840
841 if (!this->allocateStorage(dstInfo)) {
842 return kInternalError;
843 }
844
845 return kSuccess;
846}
int32_t width
constexpr int32_t x() const
Definition SkRect.h:141
constexpr int32_t height() const
Definition SkRect.h:165
constexpr int32_t right() const
Definition SkRect.h:127
constexpr int32_t width() const
Definition SkRect.h:158
void setXYWH(int32_t x, int32_t y, int32_t width, int32_t height)
Definition SkRect.h:268

Friends And Related Symbol 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: