gfx/layers/ImageDataSerializer.cpp

changeset 0
6474c204b198
     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

mercurial