1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/layers/ImageDataSerializer.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,161 @@ 1.4 +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- 1.5 + * This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "ImageDataSerializer.h" 1.10 +#include "gfx2DGlue.h" // for SurfaceFormatToImageFormat 1.11 +#include "gfxImageSurface.h" // for gfxImageSurface 1.12 +#include "gfxPoint.h" // for gfxIntSize 1.13 +#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc 1.14 +#include "mozilla/gfx/2D.h" // for DataSourceSurface, Factory 1.15 +#include "mozilla/gfx/Tools.h" // for GetAlignedStride, etc 1.16 +#include "mozilla/mozalloc.h" // for operator delete, etc 1.17 + 1.18 +namespace mozilla { 1.19 +namespace layers { 1.20 + 1.21 +using namespace gfx; 1.22 + 1.23 +// The Data is layed out as follows: 1.24 +// 1.25 +// +-------------------+ -++ --+ <-- ImageDataSerializerBase::mData pointer 1.26 +// | SurfaceBufferInfo | | | 1.27 +// +-------------------+ --+ | offset 1.28 +// | ... | | 1.29 +// +-------------------+ ------+ 1.30 +// | | 1.31 +// | data | 1.32 +// | | 1.33 +// +-------------------+ 1.34 + 1.35 +// Structure written at the beginning of the data blob containing the image 1.36 +// (as shown in the figure above). It contains the necessary informations to 1.37 +// read the image in the blob. 1.38 +namespace { 1.39 +struct SurfaceBufferInfo 1.40 +{ 1.41 + uint32_t width; 1.42 + uint32_t height; 1.43 + SurfaceFormat format; 1.44 + 1.45 + static uint32_t GetOffset() 1.46 + { 1.47 + return GetAlignedStride<16>(sizeof(SurfaceBufferInfo)); 1.48 + } 1.49 +}; 1.50 +} // anonymous namespace 1.51 + 1.52 +static SurfaceBufferInfo* 1.53 +GetBufferInfo(uint8_t* aData, size_t aDataSize) 1.54 +{ 1.55 + return aDataSize >= sizeof(SurfaceBufferInfo) 1.56 + ? reinterpret_cast<SurfaceBufferInfo*>(aData) 1.57 + : nullptr; 1.58 +} 1.59 + 1.60 +void 1.61 +ImageDataSerializer::InitializeBufferInfo(IntSize aSize, 1.62 + SurfaceFormat aFormat) 1.63 +{ 1.64 + SurfaceBufferInfo* info = GetBufferInfo(mData, mDataSize); 1.65 + MOZ_ASSERT(info); // OK to assert here, this method is client-side-only 1.66 + info->width = aSize.width; 1.67 + info->height = aSize.height; 1.68 + info->format = aFormat; 1.69 + Validate(); 1.70 +} 1.71 + 1.72 +static inline uint32_t 1.73 +ComputeStride(SurfaceFormat aFormat, uint32_t aWidth) 1.74 +{ 1.75 + return GetAlignedStride<4>(BytesPerPixel(aFormat) * aWidth); 1.76 +} 1.77 + 1.78 +uint32_t 1.79 +ImageDataSerializerBase::ComputeMinBufferSize(IntSize aSize, 1.80 + SurfaceFormat aFormat) 1.81 +{ 1.82 + uint32_t bufsize = aSize.height * ComputeStride(aFormat, aSize.width); 1.83 + return SurfaceBufferInfo::GetOffset() 1.84 + + GetAlignedStride<16>(bufsize); 1.85 +} 1.86 + 1.87 +void 1.88 +ImageDataSerializerBase::Validate() 1.89 +{ 1.90 + mIsValid = false; 1.91 + if (!mData) { 1.92 + return; 1.93 + } 1.94 + SurfaceBufferInfo* info = GetBufferInfo(mData, mDataSize); 1.95 + if (!info) { 1.96 + return; 1.97 + } 1.98 + size_t requiredSize = 1.99 + ComputeMinBufferSize(IntSize(info->width, info->height), info->format); 1.100 + mIsValid = requiredSize <= mDataSize; 1.101 +} 1.102 + 1.103 +uint8_t* 1.104 +ImageDataSerializerBase::GetData() 1.105 +{ 1.106 + MOZ_ASSERT(IsValid()); 1.107 + return mData + SurfaceBufferInfo::GetOffset(); 1.108 +} 1.109 + 1.110 +uint32_t 1.111 +ImageDataSerializerBase::GetStride() const 1.112 +{ 1.113 + MOZ_ASSERT(IsValid()); 1.114 + SurfaceBufferInfo* info = GetBufferInfo(mData, mDataSize); 1.115 + return ComputeStride(GetFormat(), info->width); 1.116 +} 1.117 + 1.118 +IntSize 1.119 +ImageDataSerializerBase::GetSize() const 1.120 +{ 1.121 + MOZ_ASSERT(IsValid()); 1.122 + SurfaceBufferInfo* info = GetBufferInfo(mData, mDataSize); 1.123 + return IntSize(info->width, info->height); 1.124 +} 1.125 + 1.126 +SurfaceFormat 1.127 +ImageDataSerializerBase::GetFormat() const 1.128 +{ 1.129 + MOZ_ASSERT(IsValid()); 1.130 + return GetBufferInfo(mData, mDataSize)->format; 1.131 +} 1.132 + 1.133 +TemporaryRef<gfxImageSurface> 1.134 +ImageDataSerializerBase::GetAsThebesSurface() 1.135 +{ 1.136 + MOZ_ASSERT(IsValid()); 1.137 + IntSize size = GetSize(); 1.138 + return new gfxImageSurface(GetData(), 1.139 + gfxIntSize(size.width, size.height), 1.140 + GetStride(), 1.141 + SurfaceFormatToImageFormat(GetFormat())); 1.142 +} 1.143 + 1.144 +TemporaryRef<DrawTarget> 1.145 +ImageDataSerializerBase::GetAsDrawTarget(gfx::BackendType aBackend) 1.146 +{ 1.147 + MOZ_ASSERT(IsValid()); 1.148 + return gfx::Factory::CreateDrawTargetForData(aBackend, 1.149 + GetData(), GetSize(), 1.150 + GetStride(), GetFormat()); 1.151 +} 1.152 + 1.153 +TemporaryRef<gfx::DataSourceSurface> 1.154 +ImageDataSerializerBase::GetAsSurface() 1.155 +{ 1.156 + MOZ_ASSERT(IsValid()); 1.157 + return Factory::CreateWrappingDataSourceSurface(GetData(), 1.158 + GetStride(), 1.159 + GetSize(), 1.160 + GetFormat()); 1.161 +} 1.162 + 1.163 +} // namespace layers 1.164 +} // namespace mozilla