image/decoders/nsIconDecoder.cpp

branch
TOR_BUG_9701
changeset 10
ac0c01689b40
equal deleted inserted replaced
-1:000000000000 0:42ffae9f8961
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
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/. */
6
7 #include "nsIconDecoder.h"
8 #include "nsIInputStream.h"
9 #include "RasterImage.h"
10 #include "nspr.h"
11 #include "nsRect.h"
12
13 #include "nsError.h"
14 #include <algorithm>
15
16 namespace mozilla {
17 namespace image {
18
19 nsIconDecoder::nsIconDecoder(RasterImage &aImage)
20 : Decoder(aImage),
21 mWidth(-1),
22 mHeight(-1),
23 mPixBytesRead(0),
24 mState(iconStateStart)
25 {
26 // Nothing to do
27 }
28
29 nsIconDecoder::~nsIconDecoder()
30 { }
31
32 void
33 nsIconDecoder::WriteInternal(const char *aBuffer, uint32_t aCount, DecodeStrategy)
34 {
35 NS_ABORT_IF_FALSE(!HasError(), "Shouldn't call WriteInternal after error!");
36
37 // We put this here to avoid errors about crossing initialization with case
38 // jumps on linux.
39 uint32_t bytesToRead = 0;
40
41 // Loop until the input data is gone
42 while (aCount > 0) {
43 switch (mState) {
44 case iconStateStart:
45
46 // Grab the width
47 mWidth = (uint8_t)*aBuffer;
48
49 // Book Keeping
50 aBuffer++;
51 aCount--;
52 mState = iconStateHaveHeight;
53 break;
54
55 case iconStateHaveHeight:
56
57 // Grab the Height
58 mHeight = (uint8_t)*aBuffer;
59
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;
66 }
67
68 // If We're doing a size decode, we're done
69 if (IsSizeDecode()) {
70 mState = iconStateFinished;
71 break;
72 }
73
74 if (!mImageData) {
75 PostDecoderError(NS_ERROR_OUT_OF_MEMORY);
76 return;
77 }
78
79 // Book Keeping
80 aBuffer++;
81 aCount--;
82 mState = iconStateReadPixels;
83 break;
84
85 case iconStateReadPixels:
86 {
87
88 // How many bytes are we reading?
89 bytesToRead = std::min(aCount, mImageDataLength - mPixBytesRead);
90
91 // Copy the bytes
92 memcpy(mImageData + mPixBytesRead, aBuffer, bytesToRead);
93
94 // Performance isn't critical here, so our update rectangle is
95 // always the full icon
96 nsIntRect r(0, 0, mWidth, mHeight);
97
98 // Invalidate
99 PostInvalidation(r);
100
101 // Book Keeping
102 aBuffer += bytesToRead;
103 aCount -= bytesToRead;
104 mPixBytesRead += bytesToRead;
105
106 // If we've got all the pixel bytes, we're finished
107 if (mPixBytesRead == mImageDataLength) {
108 PostFrameStop();
109 PostDecodeDone();
110 mState = iconStateFinished;
111 }
112 break;
113 }
114
115 case iconStateFinished:
116
117 // Consume all excess data silently
118 aCount = 0;
119
120 break;
121 }
122 }
123 }
124
125 } // namespace image
126 } // namespace mozilla

mercurial