image/src/Decoder.h

Thu, 15 Jan 2015 15:59:08 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 15:59:08 +0100
branch
TOR_BUG_9701
changeset 10
ac0c01689b40
permissions
-rw-r--r--

Implement a real Private Browsing Mode condition by changing the API/ABI;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #ifndef MOZILLA_IMAGELIB_DECODER_H_
     7 #define MOZILLA_IMAGELIB_DECODER_H_
     9 #include "RasterImage.h"
    10 #include "imgDecoderObserver.h"
    11 #include "mozilla/RefPtr.h"
    12 #include "DecodeStrategy.h"
    13 #include "ImageMetadata.h"
    14 #include "Orientation.h"
    15 #include "mozilla/Telemetry.h"
    17 namespace mozilla {
    18 namespace image {
    20 class Decoder
    21 {
    22 public:
    24   Decoder(RasterImage& aImage);
    25   virtual ~Decoder();
    27   /**
    28    * Initialize an image decoder. Decoders may not be re-initialized.
    29    *
    30    * Notifications Sent: TODO
    31    */
    32   void Init();
    34   /**
    35    * Initializes a decoder whose image and observer is already being used by a
    36    * parent decoder. Decoders may not be re-initialized.
    37    *
    38    * Notifications Sent: TODO
    39    */
    40   void InitSharedDecoder(uint8_t* imageData, uint32_t imageDataLength,
    41                          uint32_t* colormap, uint32_t colormapSize,
    42                          imgFrame* currentFrame);
    44   /**
    45    * Writes data to the decoder.
    46    *
    47    * @param aBuffer buffer containing the data to be written
    48    * @param aCount the number of bytes to write
    49    *
    50    * Any errors are reported by setting the appropriate state on the decoder.
    51    *
    52    * Notifications Sent: TODO
    53    */
    54   void Write(const char* aBuffer, uint32_t aCount, DecodeStrategy aStrategy);
    56   /**
    57    * Informs the decoder that all the data has been written.
    58    *
    59    * Notifications Sent: TODO
    60    */
    61   void Finish(RasterImage::eShutdownIntent aShutdownIntent);
    63   /**
    64    * Informs the shared decoder that all the data has been written.
    65    * Should only be used if InitSharedDecoder was useed
    66    *
    67    * Notifications Sent: TODO
    68    */
    69   void FinishSharedDecoder();
    71   /**
    72    * Tells the decoder to flush any pending invalidations. This informs the image
    73    * frame of its decoded region, and sends the appropriate OnDataAvailable call
    74    * to consumers.
    75    *
    76    * This can be called any time when we're midway through decoding a frame,
    77    * and must be called after finishing a frame (before starting a new one).
    78    */
    79   void FlushInvalidations();
    81   // We're not COM-y, so we don't get refcounts by default
    82   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(Decoder)
    84   /*
    85    * State.
    86    */
    88   // If we're doing a "size decode", we more or less pass through the image
    89   // data, stopping only to scoop out the image dimensions. A size decode
    90   // must be enabled by SetSizeDecode() _before_calling Init().
    91   bool IsSizeDecode() { return mSizeDecode; }
    92   void SetSizeDecode(bool aSizeDecode)
    93   {
    94     NS_ABORT_IF_FALSE(!mInitialized, "Can't set size decode after Init()!");
    95     mSizeDecode = aSizeDecode;
    96   }
    98   void SetObserver(imgDecoderObserver* aObserver)
    99   {
   100     MOZ_ASSERT(aObserver);
   101     mObserver = aObserver;
   102   }
   104   // The number of frames we have, including anything in-progress. Thus, this
   105   // is only 0 if we haven't begun any frames.
   106   uint32_t GetFrameCount() { return mFrameCount; }
   108   // The number of complete frames we have (ie, not including anything in-progress).
   109   uint32_t GetCompleteFrameCount() { return mInFrame ? mFrameCount - 1 : mFrameCount; }
   111   // Error tracking
   112   bool HasError() { return HasDataError() || HasDecoderError(); }
   113   bool HasDataError() { return mDataError; }
   114   bool HasDecoderError() { return NS_FAILED(mFailCode); }
   115   nsresult GetDecoderError() { return mFailCode; }
   116   void PostResizeError() { PostDataError(); }
   117   bool GetDecodeDone() const {
   118     return mDecodeDone;
   119   }
   121   // flags.  Keep these in sync with imgIContainer.idl.
   122   // SetDecodeFlags must be called before Init(), otherwise
   123   // default flags are assumed.
   124   enum {
   125     DECODER_NO_PREMULTIPLY_ALPHA = 0x2,     // imgIContainer::FLAG_DECODE_NO_PREMULTIPLY_ALPHA
   126     DECODER_NO_COLORSPACE_CONVERSION = 0x4  // imgIContainer::FLAG_DECODE_NO_COLORSPACE_CONVERSION
   127   };
   129   enum DecodeStyle {
   130       PROGRESSIVE, // produce intermediate frames representing the partial state of the image
   131       SEQUENTIAL // decode to final image immediately
   132   };
   134   void SetDecodeFlags(uint32_t aFlags) { mDecodeFlags = aFlags; }
   135   uint32_t GetDecodeFlags() { return mDecodeFlags; }
   137   bool HasSize() const { return mImageMetadata.HasSize(); }
   138   void SetSizeOnImage();
   140   // Use HistogramCount as an invalid Histogram ID
   141   virtual Telemetry::ID SpeedHistogram() { return Telemetry::HistogramCount; }
   143   ImageMetadata& GetImageMetadata() { return mImageMetadata; }
   145   // Tell the decoder infrastructure to allocate a frame. By default, frame 0
   146   // is created as an ARGB frame with no offset and with size width * height.
   147   // If decoders need something different, they must ask for it.
   148   // This is called by decoders when they need a new frame. These decoders
   149   // must then save the data they have been sent but not yet processed and
   150   // return from WriteInternal. When the new frame is created, WriteInternal
   151   // will be called again with nullptr and 0 as arguments.
   152   void NeedNewFrame(uint32_t frameNum, uint32_t x_offset, uint32_t y_offset,
   153                     uint32_t width, uint32_t height,
   154                     gfxImageFormat format,
   155                     uint8_t palette_depth = 0);
   157   virtual bool NeedsNewFrame() const { return mNeedsNewFrame; }
   159   // Try to allocate a frame as described in mNewFrameData and return the
   160   // status code from that attempt. Clears mNewFrameData.
   161   virtual nsresult AllocateFrame();
   163   // Called when a chunk of decoding has been done and the frame needs to be
   164   // marked as dirty. Must be called only on the main thread.
   165   void MarkFrameDirty();
   167   imgFrame* GetCurrentFrame() const { return mCurrentFrame; }
   169 protected:
   171   /*
   172    * Internal hooks. Decoder implementations may override these and
   173    * only these methods.
   174    */
   175   virtual void InitInternal();
   176   virtual void WriteInternal(const char* aBuffer, uint32_t aCount, DecodeStrategy aStrategy);
   177   virtual void FinishInternal();
   179   /*
   180    * Progress notifications.
   181    */
   183   // Called by decoders when they determine the size of the image. Informs
   184   // the image of its size and sends notifications.
   185   void PostSize(int32_t aWidth,
   186                 int32_t aHeight,
   187                 Orientation aOrientation = Orientation());
   189   // Called by decoders when they begin a frame. Informs the image, sends
   190   // notifications, and does internal book-keeping.
   191   void PostFrameStart();
   193   // Called by decoders when they end a frame. Informs the image, sends
   194   // notifications, and does internal book-keeping.
   195   // Specify whether this frame is opaque as an optimization.
   196   // For animated images, specify the disposal, blend method and timeout for
   197   // this frame.
   198   void PostFrameStop(FrameBlender::FrameAlpha aFrameAlpha = FrameBlender::kFrameHasAlpha,
   199                      FrameBlender::FrameDisposalMethod aDisposalMethod = FrameBlender::kDisposeKeep,
   200                      int32_t aTimeout = 0,
   201                      FrameBlender::FrameBlendMethod aBlendMethod = FrameBlender::kBlendOver);
   203   // Called by the decoders when they have a region to invalidate. We may not
   204   // actually pass these invalidations on right away.
   205   void PostInvalidation(nsIntRect& aRect);
   207   // Called by the decoders when they have successfully decoded the image. This
   208   // may occur as the result of the decoder getting to the appropriate point in
   209   // the stream, or by us calling FinishInternal().
   210   //
   211   // May not be called mid-frame.
   212   //
   213   // For animated images, specify the loop count. -1 means loop forever, 0
   214   // means a single iteration, stopping on the last frame.
   215   void PostDecodeDone(int32_t aLoopCount = 0);
   217   // Data errors are the fault of the source data, decoder errors are our fault
   218   void PostDataError();
   219   void PostDecoderError(nsresult aFailCode);
   221   /*
   222    * Member variables.
   223    *
   224    */
   225   RasterImage &mImage;
   226   imgFrame* mCurrentFrame;
   227   RefPtr<imgDecoderObserver> mObserver;
   228   ImageMetadata mImageMetadata;
   230   uint8_t* mImageData;       // Pointer to image data in either Cairo or 8bit format
   231   uint32_t mImageDataLength;
   232   uint32_t* mColormap;       // Current colormap to be used in Cairo format
   233   uint32_t mColormapSize;
   235   uint32_t mDecodeFlags;
   236   bool mDecodeDone;
   237   bool mDataError;
   239 private:
   240   uint32_t mFrameCount; // Number of frames, including anything in-progress
   242   nsIntRect mInvalidRect; // Tracks an invalidation region in the current frame.
   244   nsresult mFailCode;
   246   struct NewFrameData
   247   {
   248     NewFrameData()
   249     {}
   251     NewFrameData(uint32_t num, uint32_t offsetx, uint32_t offsety,
   252                  uint32_t width, uint32_t height,
   253                  gfxImageFormat format, uint8_t paletteDepth)
   254       : mFrameNum(num)
   255       , mOffsetX(offsetx)
   256       , mOffsetY(offsety)
   257       , mWidth(width)
   258       , mHeight(height)
   259       , mFormat(format)
   260       , mPaletteDepth(paletteDepth)
   261     {}
   262     uint32_t mFrameNum;
   263     uint32_t mOffsetX;
   264     uint32_t mOffsetY;
   265     uint32_t mWidth;
   266     uint32_t mHeight;
   267     gfxImageFormat mFormat;
   268     uint8_t mPaletteDepth;
   269   };
   270   NewFrameData mNewFrameData;
   271   bool mNeedsNewFrame;
   272   bool mInitialized;
   273   bool mSizeDecode;
   274   bool mInFrame;
   275   bool mIsAnimated;
   276 };
   278 } // namespace image
   279 } // namespace mozilla
   281 #endif // MOZILLA_IMAGELIB_DECODER_H_

mercurial