Index: Source/core/platform/graphics/DecodingImageGenerator.cpp |
diff --git a/Source/core/platform/graphics/DecodingImageGenerator.cpp b/Source/core/platform/graphics/DecodingImageGenerator.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..70dc2a817d4f42fe3d20fc93838513d45fdb1c08 |
--- /dev/null |
+++ b/Source/core/platform/graphics/DecodingImageGenerator.cpp |
@@ -0,0 +1,160 @@ |
+/* |
+ * Copyright (C) 2013 Google Inc. All rights reserved. |
+ * |
+ * Redistribution and use in source and binary forms, with or without |
+ * modification, are permitted provided that the following conditions |
+ * are met: |
+ * 1. Redistributions of source code must retain the above copyright |
+ * notice, this list of conditions and the following disclaimer. |
+ * 2. Redistributions in binary form must reproduce the above copyright |
+ * notice, this list of conditions and the following disclaimer in the |
+ * documentation and/or other materials provided with the distribution. |
+ * |
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY |
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR |
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
+ */ |
+ |
+//////////////////////////////////////////////////////////////////////////////// |
+#include "config.h" |
+ |
+#include "DecodingImageGenerator.h" |
+ |
+#include "ImageDecodingStore.h" |
+#include "ImageFrameGenerator.h" |
+#include "SkData.h" |
+#include "platform/Logging.h" |
+#include "platform/TraceEvent.h" |
+#include "skia/ext/image_operations.h" |
+#include "third_party/skia/src/lazy/SkDiscardablePixelRef.h" |
+ |
+//////////////////////////////////////////////////////////////////////////////// |
+namespace WebCore { |
+ |
+namespace { |
+ |
+#ifndef NDEBUG |
+inline bool operator==(const IntSize& lhs, const SkISize& rhs) |
+{ |
+ return (lhs.width() == rhs.width()) && (lhs.height() == rhs.height()); |
+} |
+#endif |
+ |
+inline SkImageInfo sizeToImageInfo(const SkISize& size) |
+{ |
+ SkImageInfo info; |
+ info.fWidth = size.width(); |
+ info.fHeight = size.height(); |
+ info.fColorType = kPMColor_SkColorType; |
+ info.fAlphaType = kPremul_SkAlphaType; |
+ return info; |
+} |
+ |
+bool copyFrame(const SkBitmap& bitmap, void* pixels, size_t rowBytes) |
+{ |
+ SkAutoLockPixels autoLockPixels(bitmap); |
+ void* bitmapPixels = bitmap.getPixels(); |
+ size_t bitmapRowBytes = bitmap.rowBytes(); |
+ size_t bytesPerLine = bitmap.bytesPerPixel() * bitmap.width(); |
+ ASSERT(bytesPerLine <= rowBytes); |
+ for (int row = 0; row < bitmap.height(); ++row) { |
+ // This memcpy() is wasteful and bad. |
+ // More refactoring should remove it. |
+ memcpy(pixels, bitmapPixels, bytesPerLine); |
+ pixels = static_cast<char*>(pixels) + rowBytes; |
+ bitmapPixels = static_cast<char*>(bitmapPixels) + bitmapRowBytes; |
+ } |
+ return true; |
+} |
+ |
+} // namespace |
+//////////////////////////////////////////////////////////////////////////////// |
+ |
+SkData* DecodingImageGenerator::refEncodedData() |
+{ |
+ RefPtr<SharedBuffer> buffer = 0; |
+ bool allDataReceived = false; |
+ m_frameGenerator->copyData(&buffer, &allDataReceived); |
+ if (buffer && allDataReceived) { |
+ const void* data = static_cast<const void*>(buffer->data()); |
+ size_t size = buffer->size(); |
+ return SkData::NewWithCopy(data, size); |
+ } |
+ return 0; |
+} |
+ |
+bool DecodingImageGenerator::Install(PassRefPtr<ImageFrameGenerator> frameGenerator, size_t index, SkBitmap* dst) |
+{ |
+ SkASSERT(dst); |
+ DecodingImageGenerator* gen(SkNEW_ARGS(DecodingImageGenerator, (frameGenerator, index))); |
+ return SkDiscardablePixelRef::Install(gen, dst); |
+} |
+ |
+DecodingImageGenerator::DecodingImageGenerator(PassRefPtr<ImageFrameGenerator> frameGenerator, size_t index) |
+ : m_frameGenerator(frameGenerator) |
+ , m_frameIndex(index) |
+{ |
+} |
+ |
+DecodingImageGenerator::~DecodingImageGenerator() |
+{ |
+} |
+ |
+bool DecodingImageGenerator::getInfo(SkImageInfo* info) |
+{ |
+ ASSERT(info); |
+ SkISize size = m_frameGenerator->getFullSize(); |
+ if ((size.width() <= 0) || (size.height() <= 0)) { |
+ return false; |
+ } |
+ *info = sizeToImageInfo(size); |
+ return true; |
+} |
+ |
+bool DecodingImageGenerator::getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes) |
+{ |
+ if (info != sizeToImageInfo(m_frameGenerator->getFullSize())) { |
+ return false; |
+ } |
+ RefPtr<SharedBuffer> data(0); |
+ bool allDataReceived = false; |
+ |
+ m_frameGenerator->copyData(&data, &allDataReceived); |
+ |
+ ASSERT(data); |
+ |
+ OwnPtr<ImageDecoder> decoder( |
+ ImageDecoder::create(*data, ImageSource::AlphaPremultiplied, |
+ ImageSource::GammaAndColorProfileApplied)); |
+ if (!decoder.get()) { |
+ return false; |
+ } |
+ decoder->setData(data.get(), allDataReceived); |
+ |
+ if (!decoder->isSizeAvailable()) { |
+ return false; |
+ } |
+ ASSERT(decoder->frameSizeAtIndex(m_frameIndex) |
+ == m_frameGenerator->getFullSize()); |
+ |
+ ImageFrame* frame = 0; |
+ frame = decoder->frameBufferAtIndex(m_frameIndex); |
+ if (frame) { |
+ ASSERT(frame->getSkBitmap().width() == info.fWidth); |
+ ASSERT(frame->getSkBitmap().height() == info.fHeight); |
+ // FIXME: copyFrame is wasteful. |
+ copyFrame(frame->getSkBitmap(), pixels, rowBytes); |
+ // FIXME: find some way to convince the ImageFrameGenerator to |
+ // release the memory. |
+ } |
+ return frame; |
+} |
+} // namespace WebCore |