Bumping manifests a=b2g-bump
[gecko.git] / image / decoders / nsIconDecoder.cpp
blobf4c8335dba26397100b314243b0cefbbc23f1b9d
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 "nspr.h"
10 #include "nsRect.h"
11 #include "nsError.h"
12 #include "RasterImage.h"
13 #include <algorithm>
15 namespace mozilla {
16 namespace image {
18 nsIconDecoder::nsIconDecoder(RasterImage* aImage)
19 : Decoder(aImage),
20 mWidth(-1),
21 mHeight(-1),
22 mPixBytesRead(0),
23 mState(iconStateStart)
25 // Nothing to do
28 nsIconDecoder::~nsIconDecoder()
29 { }
31 void
32 nsIconDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
34 NS_ABORT_IF_FALSE(!HasError(), "Shouldn't call WriteInternal after error!");
36 // We put this here to avoid errors about crossing initialization with case
37 // jumps on linux.
38 uint32_t bytesToRead = 0;
40 // Loop until the input data is gone
41 while (aCount > 0) {
42 switch (mState) {
43 case iconStateStart:
45 // Grab the width
46 mWidth = (uint8_t)*aBuffer;
48 // Book Keeping
49 aBuffer++;
50 aCount--;
51 mState = iconStateHaveHeight;
52 break;
54 case iconStateHaveHeight:
56 // Grab the Height
57 mHeight = (uint8_t)*aBuffer;
59 // Post our size to the superclass
60 PostSize(mWidth, mHeight);
62 PostHasTransparency();
64 if (HasError()) {
65 // Setting the size led to an error.
66 mState = iconStateFinished;
67 return;
70 // If We're doing a size decode, we're done
71 if (IsSizeDecode()) {
72 mState = iconStateFinished;
73 break;
76 if (!mImageData) {
77 PostDecoderError(NS_ERROR_OUT_OF_MEMORY);
78 return;
81 // Book Keeping
82 aBuffer++;
83 aCount--;
84 mState = iconStateReadPixels;
85 break;
87 case iconStateReadPixels: {
89 // How many bytes are we reading?
90 bytesToRead = std::min(aCount, mImageDataLength - mPixBytesRead);
92 // Copy the bytes
93 memcpy(mImageData + mPixBytesRead, aBuffer, bytesToRead);
95 // Performance isn't critical here, so our update rectangle is
96 // always the full icon
97 nsIntRect r(0, 0, mWidth, mHeight);
99 // Invalidate
100 PostInvalidation(r);
102 // Book Keeping
103 aBuffer += bytesToRead;
104 aCount -= bytesToRead;
105 mPixBytesRead += bytesToRead;
107 // If we've got all the pixel bytes, we're finished
108 if (mPixBytesRead == mImageDataLength) {
109 PostFrameStop();
110 PostDecodeDone();
111 mState = iconStateFinished;
113 break;
116 case iconStateFinished:
118 // Consume all excess data silently
119 aCount = 0;
121 break;
126 } // namespace image
127 } // namespace mozilla