/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// This class should be placed inside GetBRGADataSourceSurfaceSync(). However, // due to B2G ICS uses old complier (C++98/03) which forbids local class as // template parameter, we need to move this class outside. class SurfaceHelper : public Runnable { public: explicit SurfaceHelper(already_AddRefed<layers::Image> aImage)
: Runnable("SurfaceHelper"), mImage(aImage) {}
// It retrieves a SourceSurface reference and convert color format on main // thread and passes DataSourceSurface to caller thread.
NS_IMETHOD Run() override {
RefPtr<gfx::SourceSurface> surface = mImage->GetAsSourceSurface();
// This function returns a DataSourceSurface in B8G8R8A8 format. // It uses SourceSurface to do format convert. Because most SourceSurface in // image formats should be referenced or dereferenced on main thread, it uses a // sync class SurfaceHelper to retrieve SourceSurface and convert to B8G8R8A8 on // main thread.
already_AddRefed<DataSourceSurface> GetBRGADataSourceSurfaceSync(
already_AddRefed<layers::Image> aImage) {
RefPtr<SurfaceHelper> helper = new SurfaceHelper(std::move(aImage)); return helper->GetDataSurfaceSafe();
}
class EncodingCompleteEvent final : public DiscardableRunnable { virtual ~EncodingCompleteEvent() = default;
// If there are unrecognized custom parse options, we should fall back to // the default values for the encoder without any options at all. if (rv == NS_ERROR_INVALID_ARG && mUsingCustomOptions) {
rv = ImageEncoder::ExtractDataInternal(
mType, u""_ns, mImageBuffer.get(), mFormat, mSize, mUsePlaceholder,
mImage, nullptr, nullptr, getter_AddRefs(stream), mEncoder);
}
NS_ENSURE_SUCCESS(rv, rv);
const RefPtr<DataSourceSurface> data = snapshot->GetDataSurface(); if (!data) { return NS_ERROR_OUT_OF_MEMORY;
}
{
DataSourceSurface::MappedSurface map; if (!data->Map(gfx::DataSourceSurface::MapType::READ, &map)) { return NS_ERROR_INVALID_ARG;
} auto size = data->GetSize();
rv = aEncoder->InitFromData(map.mData, size.width * size.height * 4,
size.width, size.height, size.width * 4,
imgIEncoder::INPUT_FORMAT_HOSTARGB, aOptions);
data->Unmap();
} if (NS_SUCCEEDED(rv)) {
imgStream = aEncoder;
}
} elseif (aImage && !aUsePlaceholder) { // It is safe to convert PlanarYCbCr format from YUV to RGB off-main-thread. // Other image formats could have problem to convert format off-main-thread. // So here it uses a help function GetBRGADataSourceSurfaceSync() to convert // format on main thread. if (aImage->GetFormat() == ImageFormat::PLANAR_YCBCR) {
nsTArray<uint8_t> data;
layers::PlanarYCbCrImage* ycbcrImage = static_cast<layers::PlanarYCbCrImage*>(aImage);
gfxImageFormat format = SurfaceFormat::A8R8G8B8_UINT32;
int32_t stride = GetAlignedStride<16>(aSize.width, 4);
size_t length = BufferSizeFromStrideAndHeight(stride, aSize.height); if (length == 0) { return NS_ERROR_INVALID_ARG;
}
data.SetCapacity(length);
rv = ConvertYCbCrToRGB(*ycbcrImage->GetData(), format,
aSize.ToUnknownSize(), data.Elements(), stride); if (NS_FAILED(rv)) {
MOZ_ASSERT_UNREACHABLE("Failed to convert YUV into RGB data"); return rv;
}
if (NS_SUCCEEDED(rv)) {
imgStream = aEncoder;
}
} else { if (BufferSizeFromDimensions(aSize.width, aSize.height, 4) == 0) { return NS_ERROR_INVALID_ARG;
}
// no context, so we have to encode an empty image // note that if we didn't have a current context, the spec says we're // supposed to just return transparent black pixels of the canvas // dimensions.
RefPtr<DataSourceSurface> emptyCanvas =
Factory::CreateDataSourceSurfaceWithStride(
IntSize(aSize.width, aSize.height), SurfaceFormat::B8G8R8A8,
4 * aSize.width, true); if (NS_WARN_IF(!emptyCanvas)) { return NS_ERROR_INVALID_ARG;
}
/* static */
already_AddRefed<imgIEncoder> ImageEncoder::GetImageEncoder(nsAString& aType) { // Get an image encoder for the media type.
nsCString encoderCID("@mozilla.org/image/encoder;2?type=");
NS_ConvertUTF16toUTF8 encoderType(aType);
encoderCID += encoderType;
nsCOMPtr<imgIEncoder> encoder = do_CreateInstance(encoderCID.get());
if (!encoder && aType != u"image/png"_ns) { // Unable to create an encoder instance of the specified type. Falling back // to PNG.
aType.AssignLiteral("image/png");
nsCString PNGEncoderCID("@mozilla.org/image/encoder;2?type=image/png");
encoder = do_CreateInstance(PNGEncoderCID.get());
}
return encoder.forget();
}
} // namespace mozilla::dom
¤ Dauer der Verarbeitung: 0.27 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.