DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Implementation

Mercurial (31ec81b5d7bb)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 *
 * 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/. */

#ifndef mozilla_imagelib_FrameSequence_h_
#define mozilla_imagelib_FrameSequence_h_

#include "nsTArray.h"
#include "mozilla/MemoryReporting.h"
#include "gfxASurface.h"
#include "imgFrame.h"

namespace mozilla {
namespace image {

/**
 * FrameDataPair is a slightly-smart tuple of (frame, raw frame data) where the
 * raw frame data is allowed to be (and is, initially) null.
 *
 * If you call LockAndGetData, you will be able to call GetFrameData() on that
 * instance, and when the FrameDataPair is destructed, the imgFrame lock will
 * be unlocked.
 */
class FrameDataPair
{
public:
  explicit FrameDataPair(imgFrame* frame)
    : mFrame(frame)
    , mFrameData(nullptr)
  {}

  FrameDataPair()
    : mFrame(nullptr)
    , mFrameData(nullptr)
  {}

  FrameDataPair(FrameDataPair& other)
  {
    mFrame = other.mFrame;
    mFrameData = other.mFrameData;

    // since mFrame is an nsAutoPtr, the assignment operator above actually
    // nulls out other.mFrame. In order to fully assume ownership over the
    // frame, we also null out the other's mFrameData.
    other.mFrameData = nullptr;
  }

  ~FrameDataPair()
  {
    if (mFrameData) {
      mFrame->UnlockImageData();
    }
  }

  // Lock the frame and store its mFrameData. The frame will be unlocked (and
  // deleted) when this FrameDataPair is deleted.
  void LockAndGetData()
  {
    if (mFrame) {
      if (NS_SUCCEEDED(mFrame->LockImageData())) {
        if (mFrame->GetIsPaletted()) {
          mFrameData = reinterpret_cast<uint8_t*>(mFrame->GetPaletteData());
        } else {
          mFrameData = mFrame->GetImageData();
        }
      }
    }
  }

  // Null out this FrameDataPair and return its frame. You must ensure the
  // frame will be deleted separately.
  imgFrame* Forget()
  {
    if (mFrameData) {
      mFrame->UnlockImageData();
    }

    imgFrame* frame = mFrame.forget();
    mFrameData = nullptr;
    return frame;
  }

  bool HasFrameData() const
  {
    if (mFrameData) {
      MOZ_ASSERT(!!mFrame);
    }
    return !!mFrameData;
  }

  uint8_t* GetFrameData() const
  {
    return mFrameData;
  }

  imgFrame* GetFrame() const
  {
    return mFrame;
  }

  // Resets this FrameDataPair to work with a different frame. Takes ownership
  // of the frame, deleting the old frame (if any).
  void SetFrame(imgFrame* frame)
  {
    if (mFrameData) {
      mFrame->UnlockImageData();
    }

    mFrame = frame;
    mFrameData = nullptr;
  }

  operator imgFrame*() const
  {
    return GetFrame();
  }

  imgFrame* operator->() const
  {
    return GetFrame();
  }

  bool operator==(imgFrame* other) const
  {
    return mFrame == other;
  }

private:
  nsAutoPtr<imgFrame> mFrame;
  uint8_t* mFrameData;
};

/**
 * FrameSequence stores image frames (and their associated raw data pointers).
 * It is little more than a smart array.
 */
class FrameSequence
{
public:

  ~FrameSequence();

  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(FrameSequence)

  /**
   * Get the read-only (frame, data) pair at index aIndex.
   */
  const FrameDataPair& GetFrame(uint32_t aIndex) const;

  /**
   * Insert a frame into the array. FrameSequence takes ownership of the frame.
   */
  void InsertFrame(uint32_t framenum, imgFrame* aFrame);

  /**
   * Remove (and delete) the frame at index framenum.
   */
  void RemoveFrame(uint32_t framenum);

  /**
   * Swap aFrame with the frame at sequence framenum, and return that frame.
   * You take ownership over the frame returned.
   */
  imgFrame* SwapFrame(uint32_t framenum, imgFrame* aFrame);

  /**
   * Remove (and delete) all frames.
   */
  void ClearFrames();

  /* The total number of frames in this image. */
  uint32_t GetNumFrames() const;

  size_t SizeOfDecodedWithComputedFallbackIfHeap(gfxASurface::MemoryLocation aLocation,
                                                 mozilla::MallocSizeOf aMallocSizeOf) const;

private: // data
  //! All the frames of the image
  nsTArray<FrameDataPair> mFrames;
};

} // namespace image
} // namespace mozilla

#endif /* mozilla_imagelib_FrameSequence_h_ */