From 1fcc40474f1ad1f522d0a61086e25a71ca0a6881 Mon Sep 17 00:00:00 2001 From: Hal Canary Date: Wed, 30 Nov 2016 17:07:59 -0500 Subject: SkEncodeImage: no more link-time registration Also, no more SkImageEncoder class. SK_SUPPORT_LEGACY_IMAGE_ENCODER_CLASS now only guards some old API shims. GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=5006 Change-Id: I3797f584f3e8e12ade10d31e8733163453725f40 Reviewed-on: https://skia-review.googlesource.com/5006 Commit-Queue: Hal Canary Reviewed-by: Leon Scroggins Reviewed-by: Mike Reed --- src/android/SkBitmapRegionCodec.h | 4 +- src/gpu/GrSurface.cpp | 1 + src/image/SkImage.cpp | 1 + src/images/SkForceLinking.cpp | 41 ---------- src/images/SkImageEncoder.cpp | 21 +++-- src/images/SkImageEncoderPriv.h | 69 ++++++---------- src/images/SkImageEncoder_Factory.cpp | 22 ----- src/images/SkJPEGImageEncoder.cpp | 146 ++++++++++++++++------------------ src/images/SkKTXImageEncoder.cpp | 19 +---- src/images/SkPNGImageEncoder.cpp | 84 +++++++------------ src/images/SkWEBPImageEncoder.cpp | 57 +++++-------- src/ports/SkImageEncoder_CG.cpp | 57 +++---------- src/ports/SkImageEncoder_WIC.cpp | 47 +++-------- 13 files changed, 180 insertions(+), 389 deletions(-) delete mode 100644 src/images/SkForceLinking.cpp delete mode 100644 src/images/SkImageEncoder_Factory.cpp (limited to 'src') diff --git a/src/android/SkBitmapRegionCodec.h b/src/android/SkBitmapRegionCodec.h index 2c9536c109..c59879b68d 100644 --- a/src/android/SkBitmapRegionCodec.h +++ b/src/android/SkBitmapRegionCodec.h @@ -26,9 +26,7 @@ public: bool conversionSupported(SkColorType colorType) override; - SkEncodedFormat getEncodedFormat() override { - return (SkEncodedFormat)fCodec->getEncodedFormat(); - } + SkEncodedImageFormat getEncodedFormat() override { return fCodec->getEncodedFormat(); } private: diff --git a/src/gpu/GrSurface.cpp b/src/gpu/GrSurface.cpp index 3bb666e427..83e5a05aec 100644 --- a/src/gpu/GrSurface.cpp +++ b/src/gpu/GrSurface.cpp @@ -14,6 +14,7 @@ #include "SkGrPriv.h" #include "SkImageEncoder.h" #include "SkMathPriv.h" +#include "SkStream.h" #include GrSurface::~GrSurface() { diff --git a/src/image/SkImage.cpp b/src/image/SkImage.cpp index e0436815a7..d8c3b321a6 100644 --- a/src/image/SkImage.cpp +++ b/src/image/SkImage.cpp @@ -22,6 +22,7 @@ #include "SkPixelSerializer.h" #include "SkReadPixelsRec.h" #include "SkSpecialImage.h" +#include "SkStream.h" #include "SkString.h" #include "SkSurface.h" diff --git a/src/images/SkForceLinking.cpp b/src/images/SkForceLinking.cpp deleted file mode 100644 index dfed6b4b57..0000000000 --- a/src/images/SkForceLinking.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2013 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "SkImageEncoderPriv.h" -#include "SkForceLinking.h" - -// This method is required to fool the linker into not discarding the pre-main -// initialization and registration of the encoder classes. Passing true will -// cause memory leaks. -int SkForceLinking(bool doNotPassTrue) { - if (doNotPassTrue) { - SkASSERT(false); -#if defined(SK_HAS_JPEG_LIBRARY) && !defined(SK_USE_CG_ENCODER) && !defined(SK_USE_WIC_ENCODER) - CreateJPEGImageEncoder(); -#endif -#if defined(SK_HAS_WEBP_LIBRARY) && !defined(SK_USE_CG_ENCODER) && !defined(SK_USE_WIC_ENCODER) - CreateWEBPImageEncoder(); -#endif -#if defined(SK_HAS_PNG_LIBRARY) && !defined(SK_USE_CG_ENCODER) && !defined(SK_USE_WIC_ENCODER) - CreatePNGImageEncoder(); -#endif - - // Only link hardware texture codecs on platforms that build them. See images.gyp -#ifndef SK_BUILD_FOR_ANDROID_FRAMEWORK - CreateKTXImageEncoder(); -#endif - -#if defined (SK_USE_CG_ENCODER) - CreateImageEncoder_CG(SkEncodedImageFormat::kPNG); -#endif -#if defined (SK_USE_WIC_ENCODER) - CreateImageEncoder_WIC(SkEncodedImageFormat::kPNG); -#endif - return -1; - } - return 0; -} diff --git a/src/images/SkImageEncoder.cpp b/src/images/SkImageEncoder.cpp index c137bc5e0a..c5fff08f61 100644 --- a/src/images/SkImageEncoder.cpp +++ b/src/images/SkImageEncoder.cpp @@ -9,11 +9,18 @@ bool SkEncodeImage(SkWStream* dst, const SkPixmap& src, SkEncodedImageFormat format, int quality) { - SkBitmap bm; - if (!bm.installPixels(src)) { - return false; - } - bm.setImmutable(); - std::unique_ptr enc(SkImageEncoder::Create((SkImageEncoder::Type)format)); - return enc && enc->encodeStream(dst, bm, quality); + #ifdef SK_USE_CG_ENCODER + (void)quality; + return SkEncodeImageWithCG(dst, src, format); + #elif SK_USE_WIC_ENCODER + return SkEncodeImageWithWIC(dst, src, format, quality); + #else + switch(format) { + case SkEncodedImageFormat::kJPEG: return SkEncodeImageAsJPEG(dst, src, quality); + case SkEncodedImageFormat::kPNG: return SkEncodeImageAsPNG(dst, src); + case SkEncodedImageFormat::kWEBP: return SkEncodeImageAsWEBP(dst, src, quality); + case SkEncodedImageFormat::kKTX: return SkEncodeImageAsKTX(dst, src); + default: return false; + } + #endif } diff --git a/src/images/SkImageEncoderPriv.h b/src/images/SkImageEncoderPriv.h index 9b632f5a5b..982930e8d8 100644 --- a/src/images/SkImageEncoderPriv.h +++ b/src/images/SkImageEncoderPriv.h @@ -9,60 +9,37 @@ #define SkImageEncoderPriv_DEFINED #include "SkImageEncoder.h" -#include "SkTRegistry.h" -#ifndef SK_SUPPORT_LEGACY_IMAGE_ENCODER_CLASS - - // TODO(halcanary): replace this class and registry system with something simpler. - class SkImageEncoder { - public: - typedef SkEncodedImageFormat Type; - static SkImageEncoder* Create(SkEncodedImageFormat); - - virtual ~SkImageEncoder() {} - - bool encodeStream(SkWStream* dst, const SkBitmap& src, int quality) { - return this->onEncode(dst, src, SkMin32(100, SkMax32(0, quality))); - } - - protected: - /** - * Encode bitmap 'bm' in the desired format, writing results to - * stream 'stream', at quality level 'quality' (which can be in - * range 0-100). - */ - virtual bool onEncode(SkWStream* stream, const SkBitmap& bm, int quality) = 0; - }; - -#endif // SK_SUPPORT_LEGACY_IMAGE_ENCODER_CLASS +#ifdef SK_HAS_JPEG_LIBRARY + bool SkEncodeImageAsJPEG(SkWStream*, const SkPixmap&, int quality); +#else + #define SkEncodeImageAsJPEG(...) false +#endif -// This macro declares a global (i.e., non-class owned) creation entry point -// for each encoder (e.g., CreateJPEGImageEncoder) -#define DECLARE_ENCODER_CREATOR(codec) \ - SK_API SkImageEncoder *Create ## codec (); +#ifdef SK_HAS_PNG_LIBRARY + bool SkEncodeImageAsPNG(SkWStream*, const SkPixmap&); +#else + #define SkEncodeImageAsPNG(...) false +#endif -// This macro defines the global creation entry point for each encoder. Each -// encoder implementation that registers with the encoder factory must call it. -#define DEFINE_ENCODER_CREATOR(codec) \ - SkImageEncoder* Create##codec() { return new Sk##codec; } +#ifdef SK_HAS_WEBP_LIBRARY + bool SkEncodeImageAsWEBP(SkWStream*, const SkPixmap&, int quality); +#else + #define SkEncodeImageAsWEBP(...) false +#endif -// All the encoders known by Skia. Note that, depending on the compiler settings, -// not all of these will be available -DECLARE_ENCODER_CREATOR(JPEGImageEncoder); -DECLARE_ENCODER_CREATOR(PNGImageEncoder); -DECLARE_ENCODER_CREATOR(KTXImageEncoder); -DECLARE_ENCODER_CREATOR(WEBPImageEncoder); +bool SkEncodeImageAsKTX(SkWStream*, const SkPixmap&); #if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS) -SkImageEncoder* CreateImageEncoder_CG(SkImageEncoder::Type type); + bool SkEncodeImageWithCG(SkWStream*, const SkPixmap&, SkEncodedImageFormat); +#else + #define SkEncodeImageWithCG(...) false #endif -#if defined(SK_BUILD_FOR_WIN) -SkImageEncoder* CreateImageEncoder_WIC(SkImageEncoder::Type type); +#ifdef SK_BUILD_FOR_WIN + bool SkEncodeImageWithWIC(SkWStream*, const SkPixmap&, SkEncodedImageFormat, int quality); +#else + #define SkEncodeImageWithWIC(...) false #endif -// Typedef to make registering encoder callback easier -// This has to be defined outside SkImageEncoder. :( -typedef SkTRegistry SkImageEncoder_EncodeReg; - #endif // SkImageEncoderPriv_DEFINED diff --git a/src/images/SkImageEncoder_Factory.cpp b/src/images/SkImageEncoder_Factory.cpp deleted file mode 100644 index a5ae8d0560..0000000000 --- a/src/images/SkImageEncoder_Factory.cpp +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2009 The Android Open Source Project - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "SkImageEncoderPriv.h" - -template SkImageEncoder_EncodeReg* SkImageEncoder_EncodeReg::gHead; - -SkImageEncoder* SkImageEncoder::Create(SkImageEncoder::Type t) { - SkImageEncoder* codec = nullptr; - const SkImageEncoder_EncodeReg* curr = SkImageEncoder_EncodeReg::Head(); - while (curr) { - if ((codec = curr->factory()(t)) != nullptr) { - return codec; - } - curr = curr->next(); - } - return nullptr; -} diff --git a/src/images/SkJPEGImageEncoder.cpp b/src/images/SkJPEGImageEncoder.cpp index 97b8bbc30d..b1f943be65 100644 --- a/src/images/SkJPEGImageEncoder.cpp +++ b/src/images/SkJPEGImageEncoder.cpp @@ -7,6 +7,8 @@ #include "SkImageEncoderPriv.h" +#ifdef SK_HAS_JPEG_LIBRARY + #include "SkCanvas.h" #include "SkColorPriv.h" #include "SkDither.h" @@ -83,8 +85,8 @@ static void Write_Index_RGB(uint8_t* SK_RESTRICT dst, } } -static WriteScanline ChooseWriter(const SkBitmap& bm) { - switch (bm.colorType()) { +static WriteScanline ChooseWriter(SkColorType ct) { + switch (ct) { case kN32_SkColorType: return Write_32_RGB; case kRGB_565_SkColorType: @@ -98,87 +100,73 @@ static WriteScanline ChooseWriter(const SkBitmap& bm) { } } -class SkJPEGImageEncoder : public SkImageEncoder { -protected: - virtual bool onEncode(SkWStream* stream, const SkBitmap& bm, int quality) { +bool SkEncodeImageAsJPEG(SkWStream* stream, const SkPixmap& pixmap, int quality) { #ifdef TIME_ENCODE - SkAutoTime atm("JPEG Encode"); + SkAutoTime atm("JPEG Encode"); #endif - SkAutoLockPixels alp(bm); - if (nullptr == bm.getPixels()) { - return false; - } - - jpeg_compress_struct cinfo; - skjpeg_error_mgr sk_err; - skjpeg_destination_mgr sk_wstream(stream); - - // allocate these before set call setjmp - SkAutoTMalloc oneRow; - - cinfo.err = jpeg_std_error(&sk_err); - sk_err.error_exit = skjpeg_error_exit; - if (setjmp(sk_err.fJmpBuf)) { - return false; - } - - // Keep after setjmp or mark volatile. - const WriteScanline writer = ChooseWriter(bm); - if (nullptr == writer) { - return false; - } - - jpeg_create_compress(&cinfo); - cinfo.dest = &sk_wstream; - cinfo.image_width = bm.width(); - cinfo.image_height = bm.height(); - cinfo.input_components = 3; - - // FIXME: Can we take advantage of other in_color_spaces in libjpeg-turbo? - cinfo.in_color_space = JCS_RGB; - - // The gamma value is ignored by libjpeg-turbo. - cinfo.input_gamma = 1; - - jpeg_set_defaults(&cinfo); - - // Tells libjpeg-turbo to compute optimal Huffman coding tables - // for the image. This improves compression at the cost of - // slower encode performance. - cinfo.optimize_coding = TRUE; - jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */); - - jpeg_start_compress(&cinfo, TRUE); - - const int width = bm.width(); - uint8_t* oneRowP = oneRow.reset(width * 3); - - const SkPMColor* colors = bm.getColorTable() ? bm.getColorTable()->readColors() : nullptr; - const void* srcRow = bm.getPixels(); - - while (cinfo.next_scanline < cinfo.image_height) { - JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */ - - writer(oneRowP, srcRow, width, colors); - row_pointer[0] = oneRowP; - (void) jpeg_write_scanlines(&cinfo, row_pointer, 1); - srcRow = (const void*)((const char*)srcRow + bm.rowBytes()); - } - - jpeg_finish_compress(&cinfo); - jpeg_destroy_compress(&cinfo); - - return true; + if (!pixmap.addr()) { + return false; } -}; + jpeg_compress_struct cinfo; + skjpeg_error_mgr sk_err; + skjpeg_destination_mgr sk_wstream(stream); -/////////////////////////////////////////////////////////////////////////////// -DEFINE_ENCODER_CREATOR(JPEGImageEncoder); -/////////////////////////////////////////////////////////////////////////////// + // allocate these before set call setjmp + SkAutoTMalloc oneRow; -static SkImageEncoder* sk_libjpeg_efactory(SkImageEncoder::Type t) { - return (SkEncodedImageFormat::kJPEG == (SkEncodedImageFormat)t) ? new SkJPEGImageEncoder : nullptr; -} + cinfo.err = jpeg_std_error(&sk_err); + sk_err.error_exit = skjpeg_error_exit; + if (setjmp(sk_err.fJmpBuf)) { + return false; + } + + // Keep after setjmp or mark volatile. + const WriteScanline writer = ChooseWriter(pixmap.colorType()); + if (!writer) { + return false; + } + + jpeg_create_compress(&cinfo); + cinfo.dest = &sk_wstream; + cinfo.image_width = pixmap.width(); + cinfo.image_height = pixmap.height(); + cinfo.input_components = 3; + + // FIXME: Can we take advantage of other in_color_spaces in libjpeg-turbo? + cinfo.in_color_space = JCS_RGB; + + // The gamma value is ignored by libjpeg-turbo. + cinfo.input_gamma = 1; + + jpeg_set_defaults(&cinfo); + + // Tells libjpeg-turbo to compute optimal Huffman coding tables + // for the image. This improves compression at the cost of + // slower encode performance. + cinfo.optimize_coding = TRUE; + jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */); -static SkImageEncoder_EncodeReg gEReg(sk_libjpeg_efactory); + jpeg_start_compress(&cinfo, TRUE); + + const int width = pixmap.width(); + uint8_t* oneRowP = oneRow.reset(width * 3); + + const SkPMColor* colors = pixmap.ctable() ? pixmap.ctable()->readColors() : nullptr; + const void* srcRow = pixmap.addr(); + + while (cinfo.next_scanline < cinfo.image_height) { + JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */ + + writer(oneRowP, srcRow, width, colors); + row_pointer[0] = oneRowP; + (void) jpeg_write_scanlines(&cinfo, row_pointer, 1); + srcRow = (const void*)((const char*)srcRow + pixmap.rowBytes()); + } + + jpeg_finish_compress(&cinfo); + jpeg_destroy_compress(&cinfo); + + return true; +} +#endif diff --git a/src/images/SkKTXImageEncoder.cpp b/src/images/SkKTXImageEncoder.cpp index 6717bea5f7..fb3eb7947d 100644 --- a/src/images/SkKTXImageEncoder.cpp +++ b/src/images/SkKTXImageEncoder.cpp @@ -5,13 +5,13 @@ * found in the LICENSE file. */ -#include "SkColorPriv.h" #include "SkImageEncoderPriv.h" + +#include "SkColorPriv.h" #include "SkImageGenerator.h" #include "SkPixelRef.h" #include "SkStream.h" #include "SkStreamPriv.h" -#include "SkTypes.h" #include "ktx.h" #include "etc1.h" @@ -30,17 +30,6 @@ // be represented as a full resolution 8-bit image dump with the appropriate // OpenGL defines in the header). -class SkKTXImageEncoder : public SkImageEncoder { -protected: - bool onEncode(SkWStream* stream, const SkBitmap& bitmap, int) override { - return SkKTXFile::WriteBitmapToKTX(stream, bitmap); - } -}; - -DEFINE_ENCODER_CREATOR(KTXImageEncoder); - -SkImageEncoder* sk_libktx_efactory(SkImageEncoder::Type t) { - return (SkEncodedImageFormat::kKTX == (SkEncodedImageFormat)t) ? new SkKTXImageEncoder : nullptr; +bool SkEncodeImageAsKTX(SkWStream* stream, const SkPixmap& pixmap) { + return SkKTXFile::WritePixmapToKTX(stream, pixmap); } - -static SkImageEncoder_EncodeReg gEReg(sk_libktx_efactory); diff --git a/src/images/SkPNGImageEncoder.cpp b/src/images/SkPNGImageEncoder.cpp index 4fc3a10272..16df0205f8 100644 --- a/src/images/SkPNGImageEncoder.cpp +++ b/src/images/SkPNGImageEncoder.cpp @@ -6,12 +6,16 @@ */ #include "SkImageEncoderPriv.h" + +#ifdef SK_HAS_PNG_LIBRARY + #include "SkColor.h" #include "SkColorPriv.h" #include "SkDither.h" #include "SkMath.h" #include "SkStream.h" #include "SkTemplates.h" +#include "SkUnPreMultiply.h" #include "SkUtils.h" #include "transform_scanline.h" @@ -41,9 +45,6 @@ static const bool c_suppressPNGImageDecoderWarnings{ /////////////////////////////////////////////////////////////////////////////// -#include "SkColorPriv.h" -#include "SkUnPreMultiply.h" - static void sk_error_fn(png_structp png_ptr, png_const_charp msg) { if (!c_suppressPNGImageDecoderWarnings) { SkDEBUGF(("------ png error %s\n", msg)); @@ -165,22 +166,13 @@ static inline int pack_palette(SkColorTable* ctable, png_color* SK_RESTRICT pale return numWithAlpha; } -class SkPNGImageEncoder : public SkImageEncoder { -protected: - bool onEncode(SkWStream* stream, const SkBitmap& bm, int quality) override; -private: - bool doEncode(SkWStream* stream, const SkBitmap& bm, - SkAlphaType alphaType, int colorType, - int bitDepth, SkColorType ct, - png_color_8& sig_bit); - - typedef SkImageEncoder INHERITED; -}; - -bool SkPNGImageEncoder::onEncode(SkWStream* stream, - const SkBitmap& bitmap, - int /*quality*/) { - const SkColorType ct = bitmap.colorType(); +static bool do_encode(SkWStream*, const SkPixmap&, int, int, png_color_8&); + +bool SkEncodeImageAsPNG(SkWStream* stream, const SkPixmap& pixmap) { + if (!pixmap.addr() || pixmap.info().isEmpty()) { + return false; + } + const SkColorType ct = pixmap.colorType(); switch (ct) { case kIndex_8_SkColorType: case kGray_8_SkColorType: @@ -193,7 +185,7 @@ bool SkPNGImageEncoder::onEncode(SkWStream* stream, return false; } - const SkAlphaType alphaType = bitmap.alphaType(); + const SkAlphaType alphaType = pixmap.alphaType(); switch (alphaType) { case kUnpremul_SkAlphaType: if (kARGB_4444_SkColorType == ct) { @@ -252,36 +244,26 @@ bool SkPNGImageEncoder::onEncode(SkWStream* stream, default: return false; } - - SkAutoLockPixels alp(bitmap); - // readyToDraw checks for pixels (and colortable if that is required) - if (!bitmap.readyToDraw()) { - return false; - } - - // we must do this after we have locked the pixels - SkColorTable* ctable = bitmap.getColorTable(); - if (ctable) { - if (ctable->count() == 0) { + if (kIndex_8_SkColorType == ct) { + SkColorTable* ctable = pixmap.ctable(); + if (!ctable || ctable->count() == 0) { return false; } // check if we can store in fewer than 8 bits bitDepth = computeBitDepth(ctable->count()); } - - return doEncode(stream, bitmap, alphaType, colorType, bitDepth, ct, sig_bit); + return do_encode(stream, pixmap, colorType, bitDepth, sig_bit); } -bool SkPNGImageEncoder::doEncode(SkWStream* stream, const SkBitmap& bitmap, - SkAlphaType alphaType, int colorType, - int bitDepth, SkColorType ct, - png_color_8& sig_bit) { +static bool do_encode(SkWStream* stream, const SkPixmap& pixmap, + int colorType, int bitDepth, png_color_8& sig_bit) { + SkAlphaType alphaType = pixmap.alphaType(); + SkColorType ct = pixmap.colorType(); png_structp png_ptr; png_infop info_ptr; - png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, sk_error_fn, - nullptr); + png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, sk_error_fn, nullptr); if (nullptr == png_ptr) { return false; } @@ -311,7 +293,7 @@ bool SkPNGImageEncoder::doEncode(SkWStream* stream, const SkBitmap& bitmap, * currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. REQUIRED */ - png_set_IHDR(png_ptr, info_ptr, bitmap.width(), bitmap.height(), + png_set_IHDR(png_ptr, info_ptr, pixmap.width(), pixmap.height(), bitDepth, colorType, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); @@ -320,7 +302,7 @@ bool SkPNGImageEncoder::doEncode(SkWStream* stream, const SkBitmap& bitmap, png_color paletteColors[256]; png_byte trans[256]; if (kIndex_8_SkColorType == ct) { - SkColorTable* colorTable = bitmap.getColorTable(); + SkColorTable* colorTable = pixmap.ctable(); SkASSERT(colorTable); int numTrans = pack_palette(colorTable, paletteColors, trans, alphaType); png_set_PLTE(png_ptr, info_ptr, paletteColors, colorTable->count()); @@ -332,16 +314,16 @@ bool SkPNGImageEncoder::doEncode(SkWStream* stream, const SkBitmap& bitmap, png_set_sBIT(png_ptr, info_ptr, &sig_bit); png_write_info(png_ptr, info_ptr); - const char* srcImage = (const char*)bitmap.getPixels(); - SkAutoSTMalloc<1024, char> rowStorage(bitmap.width() << 2); + const char* srcImage = (const char*)pixmap.addr(); + SkAutoSTMalloc<1024, char> rowStorage(pixmap.width() << 2); char* storage = rowStorage.get(); transform_scanline_proc proc = choose_proc(ct, alphaType); - for (int y = 0; y < bitmap.height(); y++) { + for (int y = 0; y < pixmap.height(); y++) { png_bytep row_ptr = (png_bytep)storage; - proc(storage, srcImage, bitmap.width(), SkColorTypeBytesPerPixel(ct)); + proc(storage, srcImage, pixmap.width(), SkColorTypeBytesPerPixel(ct)); png_write_rows(png_ptr, &row_ptr, 1); - srcImage += bitmap.rowBytes(); + srcImage += pixmap.rowBytes(); } png_write_end(png_ptr, info_ptr); @@ -351,12 +333,4 @@ bool SkPNGImageEncoder::doEncode(SkWStream* stream, const SkBitmap& bitmap, return true; } -/////////////////////////////////////////////////////////////////////////////// -DEFINE_ENCODER_CREATOR(PNGImageEncoder); -/////////////////////////////////////////////////////////////////////////////// - -SkImageEncoder* sk_libpng_efactory(SkImageEncoder::Type t) { - return (SkEncodedImageFormat::kPNG == (SkEncodedImageFormat)t) ? new SkPNGImageEncoder : nullptr; -} - -static SkImageEncoder_EncodeReg gEReg(sk_libpng_efactory); +#endif diff --git a/src/images/SkWEBPImageEncoder.cpp b/src/images/SkWEBPImageEncoder.cpp index 27c984ac1b..aad06ac1d3 100644 --- a/src/images/SkWEBPImageEncoder.cpp +++ b/src/images/SkWEBPImageEncoder.cpp @@ -14,11 +14,15 @@ * limitations under the License. */ -#include "SkBitmap.h" #include "SkImageEncoderPriv.h" + +#ifdef SK_HAS_WEBP_LIBRARY + +#include "SkBitmap.h" #include "SkColorPriv.h" #include "SkStream.h" #include "SkTemplates.h" +#include "SkUnPreMultiply.h" #include "SkUtils.h" // A WebP decoder only, on top of (subset of) libwebp @@ -34,8 +38,6 @@ extern "C" { #include "webp/encode.h" } -#include "SkUnPreMultiply.h" - typedef void (*ScanlineImporter)(const uint8_t* in, uint8_t* out, int width, const SkPMColor* SK_RESTRICT ctable); @@ -172,19 +174,10 @@ static int stream_writer(const uint8_t* data, size_t data_size, return stream->write(data, data_size) ? 1 : 0; } -class SkWEBPImageEncoder : public SkImageEncoder { -protected: - bool onEncode(SkWStream* stream, const SkBitmap& bm, int quality) override; - -private: - typedef SkImageEncoder INHERITED; -}; - -bool SkWEBPImageEncoder::onEncode(SkWStream* stream, const SkBitmap& bm, - int quality) { - const bool hasAlpha = !bm.isOpaque(); +bool SkEncodeImageAsWEBP(SkWStream* stream, const SkPixmap& pixmap, int quality) { + const bool hasAlpha = !pixmap.isOpaque(); int bpp = -1; - const ScanlineImporter scanline_import = ChooseImporter(bm.colorType(), hasAlpha, &bpp); + const ScanlineImporter scanline_import = ChooseImporter(pixmap.colorType(), hasAlpha, &bpp); if (nullptr == scanline_import) { return false; } @@ -192,8 +185,7 @@ bool SkWEBPImageEncoder::onEncode(SkWStream* stream, const SkBitmap& bm, return false; } - SkAutoLockPixels alp(bm); - if (nullptr == bm.getPixels()) { + if (nullptr == pixmap.addr()) { return false; } @@ -204,44 +196,33 @@ bool SkWEBPImageEncoder::onEncode(SkWStream* stream, const SkBitmap& bm, WebPPicture pic; WebPPictureInit(&pic); - pic.width = bm.width(); - pic.height = bm.height(); + pic.width = pixmap.width(); + pic.height = pixmap.height(); pic.writer = stream_writer; pic.custom_ptr = (void*)stream; - const SkPMColor* colors = bm.getColorTable() ? bm.getColorTable()->readColors() : nullptr; - const uint8_t* src = (uint8_t*)bm.getPixels(); + const SkPMColor* colors = pixmap.ctable() ? pixmap.ctable()->readColors() : nullptr; + const uint8_t* src = (uint8_t*)pixmap.addr(); const int rgbStride = pic.width * bpp; + const size_t rowBytes = pixmap.rowBytes(); // Import (for each scanline) the bit-map image (in appropriate color-space) // to RGB color space. - uint8_t* rgb = new uint8_t[rgbStride * pic.height]; + std::unique_ptr rgb(new uint8_t[rgbStride * pic.height]); for (int y = 0; y < pic.height; ++y) { - scanline_import(src + y * bm.rowBytes(), rgb + y * rgbStride, - pic.width, colors); + scanline_import(src + y * rowBytes, &rgb[y * rgbStride], pic.width, colors); } bool ok; if (bpp == 3) { - ok = SkToBool(WebPPictureImportRGB(&pic, rgb, rgbStride)); + ok = SkToBool(WebPPictureImportRGB(&pic, &rgb[0], rgbStride)); } else { - ok = SkToBool(WebPPictureImportRGBA(&pic, rgb, rgbStride)); + ok = SkToBool(WebPPictureImportRGBA(&pic, &rgb[0], rgbStride)); } - delete[] rgb; ok = ok && WebPEncode(&webp_config, &pic); WebPPictureFree(&pic); return ok; } - - -/////////////////////////////////////////////////////////////////////////////// -DEFINE_ENCODER_CREATOR(WEBPImageEncoder); -/////////////////////////////////////////////////////////////////////////////// - -static SkImageEncoder* sk_libwebp_efactory(SkImageEncoder::Type t) { - return (SkEncodedImageFormat::kWEBP == (SkEncodedImageFormat)t) ? new SkWEBPImageEncoder : nullptr; -} - -static SkImageEncoder_EncodeReg gEReg(sk_libwebp_efactory); +#endif diff --git a/src/ports/SkImageEncoder_CG.cpp b/src/ports/SkImageEncoder_CG.cpp index 0c3d22d0f6..b3fd243324 100644 --- a/src/ports/SkImageEncoder_CG.cpp +++ b/src/ports/SkImageEncoder_CG.cpp @@ -5,14 +5,14 @@ * found in the LICENSE file. */ -#include "SkTypes.h" +#include "SkImageEncoderPriv.h" + #if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS) #include "SkBitmap.h" #include "SkCGUtils.h" #include "SkColorPriv.h" #include "SkData.h" -#include "SkImageEncoderPriv.h" #include "SkStream.h" #include "SkStreamPriv.h" #include "SkTemplates.h" @@ -57,29 +57,19 @@ static CGImageDestinationRef SkStreamToImageDestination(SkWStream* stream, return CGImageDestinationCreateWithDataConsumer(consumer, type, 1, nullptr); } -class SkImageEncoder_CG : public SkImageEncoder { -public: - SkImageEncoder_CG(SkEncodedImageFormat t) : fType(t) {} - -protected: - virtual bool onEncode(SkWStream* stream, const SkBitmap& bm, int quality); - -private: - SkEncodedImageFormat fType; -}; - /* Encode bitmaps via CGImageDestination. We setup a DataConsumer which writes to our SkWStream. Since we don't reference/own the SkWStream, our consumer must only live for the duration of the onEncode() method. */ -bool SkImageEncoder_CG::onEncode(SkWStream* stream, const SkBitmap& bm, - int quality) { - // Used for converting a bitmap to 8888. - const SkBitmap* bmPtr = &bm; - SkBitmap bitmap8888; +bool SkEncodeImageWithCG(SkWStream* stream, const SkPixmap& pixmap, SkEncodedImageFormat format) { + SkBitmap bm; + if (!bm.installPixels(pixmap)) { + return false; + } + bm.setImmutable(); CFStringRef type; - switch (fType) { + switch (format) { case SkEncodedImageFormat::kICO: type = kUTTypeICO; break; @@ -99,8 +89,9 @@ bool SkImageEncoder_CG::onEncode(SkWStream* stream, const SkBitmap& bm, // : CGImageDestinationFinalize image destination does not have enough images // So instead we copy to 8888. if (bm.colorType() == kARGB_4444_SkColorType) { + SkBitmap bitmap8888; bm.copyTo(&bitmap8888, kN32_SkColorType); - bmPtr = &bitmap8888; + bm.swap(bitmap8888); } type = kUTTypePNG; break; @@ -114,7 +105,7 @@ bool SkImageEncoder_CG::onEncode(SkWStream* stream, const SkBitmap& bm, } SkAutoTCallVProc ardst(dst); - CGImageRef image = SkCreateCGImageRef(*bmPtr); + CGImageRef image = SkCreateCGImageRef(bm); if (nullptr == image) { return false; } @@ -124,28 +115,4 @@ bool SkImageEncoder_CG::onEncode(SkWStream* stream, const SkBitmap& bm, return CGImageDestinationFinalize(dst); } -/////////////////////////////////////////////////////////////////////////////// - -#ifdef SK_USE_CG_ENCODER -static SkImageEncoder* sk_imageencoder_cg_factory(SkEncodedImageFormat t) { - switch (t) { - case SkEncodedImageFormat::kICO: - case SkEncodedImageFormat::kBMP: - case SkEncodedImageFormat::kGIF: - case SkEncodedImageFormat::kJPEG: - case SkEncodedImageFormat::kPNG: - break; - default: - return nullptr; - } - return new SkImageEncoder_CG(t); -} - -static SkImageEncoder_EncodeReg gEReg(sk_imageencoder_cg_factory); -#endif - -SkImageEncoder* CreateImageEncoder_CG(SkImageEncoder::Type type) { - return new SkImageEncoder_CG((SkEncodedImageFormat)type); -} - #endif//defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS) diff --git a/src/ports/SkImageEncoder_WIC.cpp b/src/ports/SkImageEncoder_WIC.cpp index 035359e792..52f4599433 100644 --- a/src/ports/SkImageEncoder_WIC.cpp +++ b/src/ports/SkImageEncoder_WIC.cpp @@ -46,23 +46,10 @@ #undef CLSID_WICImagingFactory #endif -class SkImageEncoder_WIC : public SkImageEncoder { -public: - SkImageEncoder_WIC(SkEncodedImageFormat t) : fType(t) {} - -protected: - virtual bool onEncode(SkWStream* stream, const SkBitmap& bm, int quality); - -private: - SkEncodedImageFormat fType; -}; - -bool SkImageEncoder_WIC::onEncode(SkWStream* stream - , const SkBitmap& bitmapOrig - , int quality) -{ +bool SkEncodeImageWithWIC(SkWStream* stream, const SkPixmap& pixmap, + SkEncodedImageFormat format, int quality) { GUID type; - switch (fType) { + switch (format) { case SkEncodedImageFormat::kJPEG: type = GUID_ContainerFormatJpeg; break; @@ -72,6 +59,11 @@ bool SkImageEncoder_WIC::onEncode(SkWStream* stream default: return false; } + SkBitmap bitmapOrig; + if (!bitmapOrig.installPixels(pixmap)) { + return false; + } + bitmapOrig.setImmutable(); // First convert to BGRA if necessary. SkBitmap bitmap; @@ -97,7 +89,7 @@ bool SkImageEncoder_WIC::onEncode(SkWStream* stream size_t rowBytes = bitmap.rowBytes(); SkAutoMalloc pixelStorage; WICPixelFormatGUID formatDesired = GUID_WICPixelFormat32bppBGRA; - if (SkEncodedImageFormat::kJPEG == fType) { + if (SkEncodedImageFormat::kJPEG == format) { formatDesired = GUID_WICPixelFormat24bppBGR; rowBytes = SkAlign4(bitmap.width() * 3); pixelStorage.reset(rowBytes * bitmap.height()); @@ -216,25 +208,4 @@ bool SkImageEncoder_WIC::onEncode(SkWStream* stream return SUCCEEDED(hr); } -/////////////////////////////////////////////////////////////////////////////// - -#ifdef SK_USE_WIC_ENCODER -static SkImageEncoder* sk_imageencoder_wic_factory(SkEncodedImageFormat t) { - switch (t) { - case SkEncodedImageFormat::kPNG: - case SkEncodedImageFormat::kJPEG: - break; - default: - return nullptr; - } - return new SkImageEncoder_WIC(t); -} - -static SkImageEncoder_EncodeReg gEReg(sk_imageencoder_wic_factory); -#endif - -SkImageEncoder* CreateImageEncoder_WIC(SkImageEncoder::Type type) { - return new SkImageEncoder_WIC((SkEncodedImageFormat)type); -} - #endif // defined(SK_BUILD_FOR_WIN32) -- cgit v1.2.3