image/decoders/nsIconDecoder.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/image/decoders/nsIconDecoder.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,126 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
     1.5 + *
     1.6 + * This Source Code Form is subject to the terms of the Mozilla Public
     1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.9 +
    1.10 +#include "nsIconDecoder.h"
    1.11 +#include "nsIInputStream.h"
    1.12 +#include "RasterImage.h"
    1.13 +#include "nspr.h"
    1.14 +#include "nsRect.h"
    1.15 +
    1.16 +#include "nsError.h"
    1.17 +#include <algorithm>
    1.18 +
    1.19 +namespace mozilla {
    1.20 +namespace image {
    1.21 +
    1.22 +nsIconDecoder::nsIconDecoder(RasterImage &aImage)
    1.23 + : Decoder(aImage),
    1.24 +   mWidth(-1),
    1.25 +   mHeight(-1),
    1.26 +   mPixBytesRead(0),
    1.27 +   mState(iconStateStart)
    1.28 +{
    1.29 +  // Nothing to do
    1.30 +}
    1.31 +
    1.32 +nsIconDecoder::~nsIconDecoder()
    1.33 +{ }
    1.34 +
    1.35 +void
    1.36 +nsIconDecoder::WriteInternal(const char *aBuffer, uint32_t aCount, DecodeStrategy)
    1.37 +{
    1.38 +  NS_ABORT_IF_FALSE(!HasError(), "Shouldn't call WriteInternal after error!");
    1.39 +
    1.40 +  // We put this here to avoid errors about crossing initialization with case
    1.41 +  // jumps on linux.
    1.42 +  uint32_t bytesToRead = 0;
    1.43 +
    1.44 +  // Loop until the input data is gone
    1.45 +  while (aCount > 0) {
    1.46 +    switch (mState) {
    1.47 +      case iconStateStart:
    1.48 +
    1.49 +        // Grab the width
    1.50 +        mWidth = (uint8_t)*aBuffer;
    1.51 +
    1.52 +        // Book Keeping
    1.53 +        aBuffer++;
    1.54 +        aCount--;
    1.55 +        mState = iconStateHaveHeight;
    1.56 +        break;
    1.57 +
    1.58 +      case iconStateHaveHeight:
    1.59 +
    1.60 +        // Grab the Height
    1.61 +        mHeight = (uint8_t)*aBuffer;
    1.62 +
    1.63 +        // Post our size to the superclass
    1.64 +        PostSize(mWidth, mHeight);
    1.65 +        if (HasError()) {
    1.66 +          // Setting the size led to an error.
    1.67 +          mState = iconStateFinished;
    1.68 +          return;
    1.69 +        }
    1.70 +
    1.71 +        // If We're doing a size decode, we're done
    1.72 +        if (IsSizeDecode()) {
    1.73 +          mState = iconStateFinished;
    1.74 +          break;
    1.75 +        }
    1.76 +
    1.77 +        if (!mImageData) {
    1.78 +          PostDecoderError(NS_ERROR_OUT_OF_MEMORY);
    1.79 +          return;
    1.80 +        }
    1.81 +
    1.82 +        // Book Keeping
    1.83 +        aBuffer++;
    1.84 +        aCount--;
    1.85 +        mState = iconStateReadPixels;
    1.86 +        break;
    1.87 +
    1.88 +      case iconStateReadPixels:
    1.89 +      {
    1.90 +
    1.91 +        // How many bytes are we reading?
    1.92 +        bytesToRead = std::min(aCount, mImageDataLength - mPixBytesRead);
    1.93 +
    1.94 +        // Copy the bytes
    1.95 +        memcpy(mImageData + mPixBytesRead, aBuffer, bytesToRead);
    1.96 +
    1.97 +        // Performance isn't critical here, so our update rectangle is
    1.98 +        // always the full icon
    1.99 +        nsIntRect r(0, 0, mWidth, mHeight);
   1.100 +
   1.101 +        // Invalidate
   1.102 +        PostInvalidation(r);
   1.103 +
   1.104 +        // Book Keeping
   1.105 +        aBuffer += bytesToRead;
   1.106 +        aCount -= bytesToRead;
   1.107 +        mPixBytesRead += bytesToRead;
   1.108 +
   1.109 +        // If we've got all the pixel bytes, we're finished
   1.110 +        if (mPixBytesRead == mImageDataLength) {
   1.111 +          PostFrameStop();
   1.112 +          PostDecodeDone();
   1.113 +          mState = iconStateFinished;
   1.114 +        }
   1.115 +        break;
   1.116 +      }
   1.117 +
   1.118 +      case iconStateFinished:
   1.119 +
   1.120 +        // Consume all excess data silently
   1.121 +        aCount = 0;
   1.122 +
   1.123 +        break;
   1.124 +    }
   1.125 +  }
   1.126 +}
   1.127 +
   1.128 +} // namespace image
   1.129 +} // namespace mozilla

mercurial