Bumping manifests a=b2g-bump
[gecko.git] / image / decoders / nsIconDecoder.cpp
blob29abc0904a506e7f4578d3aa098701d1b84afd2a
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "nsIconDecoder.h"
8 #include "nsIInputStream.h"
9 #include "RasterImage.h"
10 #include "nspr.h"
11 #include "nsRect.h"
13 #include "nsError.h"
14 #include <algorithm>
16 namespace mozilla {
17 namespace image {
19 nsIconDecoder::nsIconDecoder(RasterImage &aImage)
20 : Decoder(aImage),
21 mWidth(-1),
22 mHeight(-1),
23 mPixBytesRead(0),
24 mState(iconStateStart)
26 // Nothing to do
29 nsIconDecoder::~nsIconDecoder()
30 { }
32 void
33 nsIconDecoder::WriteInternal(const char *aBuffer, uint32_t aCount, DecodeStrategy)
35 NS_ABORT_IF_FALSE(!HasError(), "Shouldn't call WriteInternal after error!");
37 // We put this here to avoid errors about crossing initialization with case
38 // jumps on linux.
39 uint32_t bytesToRead = 0;
41 // Loop until the input data is gone
42 while (aCount > 0) {
43 switch (mState) {
44 case iconStateStart:
46 // Grab the width
47 mWidth = (uint8_t)*aBuffer;
49 // Book Keeping
50 aBuffer++;
51 aCount--;
52 mState = iconStateHaveHeight;
53 break;
55 case iconStateHaveHeight:
57 // Grab the Height
58 mHeight = (uint8_t)*aBuffer;
60 // Post our size to the superclass
61 PostSize(mWidth, mHeight);
62 if (HasError()) {
63 // Setting the size led to an error.
64 mState = iconStateFinished;
65 return;
68 // If We're doing a size decode, we're done
69 if (IsSizeDecode()) {
70 mState = iconStateFinished;
71 break;
74 if (!mImageData) {
75 PostDecoderError(NS_ERROR_OUT_OF_MEMORY);
76 return;
79 // Book Keeping
80 aBuffer++;
81 aCount--;
82 mState = iconStateReadPixels;
83 break;
85 case iconStateReadPixels:
88 // How many bytes are we reading?
89 bytesToRead = std::min(aCount, mImageDataLength - mPixBytesRead);
91 // Copy the bytes
92 memcpy(mImageData + mPixBytesRead, aBuffer, bytesToRead);
94 // Performance isn't critical here, so our update rectangle is
95 // always the full icon
96 nsIntRect r(0, 0, mWidth, mHeight);
98 // Invalidate
99 PostInvalidation(r);
101 // Book Keeping
102 aBuffer += bytesToRead;
103 aCount -= bytesToRead;
104 mPixBytesRead += bytesToRead;
106 // If we've got all the pixel bytes, we're finished
107 if (mPixBytesRead == mImageDataLength) {
108 PostFrameStop();
109 PostDecodeDone();
110 mState = iconStateFinished;
112 break;
115 case iconStateFinished:
117 // Consume all excess data silently
118 aCount = 0;
120 break;
125 } // namespace image
126 } // namespace mozilla