std::unique_ptr<SkEncoder> SkJpegEncoder::Make(SkWStream* dst, const SkPixmap& src, const Options& options) { if (!SkPixmapIsValid(src, options.fBlendBehavior)) { return nullptr; } std::unique_ptr<SkJpegEncoderMgr> encoderMgr = SkJpegEncoderMgr::Make(dst); if (setjmp(encoderMgr->jmpBuf())) { return nullptr; } if (!encoderMgr->setParams(src.info(), options)) { return nullptr; } jpeg_set_quality(encoderMgr->cinfo(), options.fQuality, TRUE); jpeg_start_compress(encoderMgr->cinfo(), TRUE); sk_sp<SkData> icc = icc_from_color_space(src.info()); if (icc) { // Create a contiguous block of memory with the icc signature followed by the profile. sk_sp<SkData> markerData = SkData::MakeUninitialized(kICCMarkerHeaderSize + icc->size()); uint8_t* ptr = (uint8_t*) markerData->writable_data(); memcpy(ptr, kICCSig, sizeof(kICCSig)); ptr += sizeof(kICCSig); *ptr++ = 1; // This is the first marker. *ptr++ = 1; // Out of one total markers. memcpy(ptr, icc->data(), icc->size()); jpeg_write_marker(encoderMgr->cinfo(), kICCMarker, markerData->bytes(), markerData->size()); } return std::unique_ptr<SkJpegEncoder>(new SkJpegEncoder(std::move(encoderMgr), src)); }
static void set_icc(png_structp png_ptr, png_infop info_ptr, const SkImageInfo& info) { sk_sp<SkData> icc = icc_from_color_space(info); if (!icc) { return; } #if PNG_LIBPNG_VER_MAJOR > 1 || (PNG_LIBPNG_VER_MAJOR == 1 && PNG_LIBPNG_VER_MINOR >= 5) const char* name = "Skia"; png_const_bytep iccPtr = icc->bytes(); #else SkString str("Skia"); char* name = str.writable_str(); png_charp iccPtr = (png_charp) icc->writable_data(); #endif png_set_iCCP(png_ptr, info_ptr, name, 0, iccPtr, icc->size()); }