OLD | NEW |
| (Empty) |
1 | |
2 /* | |
3 * Copyright 2012 Google Inc. | |
4 * | |
5 * Use of this source code is governed by a BSD-style license that can be | |
6 * found in the LICENSE file. | |
7 */ | |
8 | |
9 #include "SkBitmap.h" | |
10 #include "SkErrorInternals.h" | |
11 #include "SkOrderedReadBuffer.h" | |
12 #include "SkStream.h" | |
13 #include "SkTypeface.h" | |
14 | |
15 SkOrderedReadBuffer::SkOrderedReadBuffer() : INHERITED() { | |
16 fMemoryPtr = NULL; | |
17 | |
18 fBitmapStorage = NULL; | |
19 fTFArray = NULL; | |
20 fTFCount = 0; | |
21 | |
22 fFactoryTDArray = NULL; | |
23 fFactoryArray = NULL; | |
24 fFactoryCount = 0; | |
25 fBitmapDecoder = NULL; | |
26 #ifdef DEBUG_NON_DETERMINISTIC_ASSERT | |
27 fDecodedBitmapIndex = -1; | |
28 #endif // DEBUG_NON_DETERMINISTIC_ASSERT | |
29 } | |
30 | |
31 SkOrderedReadBuffer::SkOrderedReadBuffer(const void* data, size_t size) : INHERI
TED() { | |
32 fReader.setMemory(data, size); | |
33 fMemoryPtr = NULL; | |
34 | |
35 fBitmapStorage = NULL; | |
36 fTFArray = NULL; | |
37 fTFCount = 0; | |
38 | |
39 fFactoryTDArray = NULL; | |
40 fFactoryArray = NULL; | |
41 fFactoryCount = 0; | |
42 fBitmapDecoder = NULL; | |
43 #ifdef DEBUG_NON_DETERMINISTIC_ASSERT | |
44 fDecodedBitmapIndex = -1; | |
45 #endif // DEBUG_NON_DETERMINISTIC_ASSERT | |
46 } | |
47 | |
48 SkOrderedReadBuffer::SkOrderedReadBuffer(SkStream* stream) { | |
49 const size_t length = stream->getLength(); | |
50 fMemoryPtr = sk_malloc_throw(length); | |
51 stream->read(fMemoryPtr, length); | |
52 fReader.setMemory(fMemoryPtr, length); | |
53 | |
54 fBitmapStorage = NULL; | |
55 fTFArray = NULL; | |
56 fTFCount = 0; | |
57 | |
58 fFactoryTDArray = NULL; | |
59 fFactoryArray = NULL; | |
60 fFactoryCount = 0; | |
61 fBitmapDecoder = NULL; | |
62 #ifdef DEBUG_NON_DETERMINISTIC_ASSERT | |
63 fDecodedBitmapIndex = -1; | |
64 #endif // DEBUG_NON_DETERMINISTIC_ASSERT | |
65 } | |
66 | |
67 SkOrderedReadBuffer::~SkOrderedReadBuffer() { | |
68 sk_free(fMemoryPtr); | |
69 SkSafeUnref(fBitmapStorage); | |
70 } | |
71 | |
72 bool SkOrderedReadBuffer::readBool() { | |
73 return fReader.readBool(); | |
74 } | |
75 | |
76 SkColor SkOrderedReadBuffer::readColor() { | |
77 return fReader.readInt(); | |
78 } | |
79 | |
80 SkFixed SkOrderedReadBuffer::readFixed() { | |
81 return fReader.readS32(); | |
82 } | |
83 | |
84 int32_t SkOrderedReadBuffer::readInt() { | |
85 return fReader.readInt(); | |
86 } | |
87 | |
88 SkScalar SkOrderedReadBuffer::readScalar() { | |
89 return fReader.readScalar(); | |
90 } | |
91 | |
92 uint32_t SkOrderedReadBuffer::readUInt() { | |
93 return fReader.readU32(); | |
94 } | |
95 | |
96 int32_t SkOrderedReadBuffer::read32() { | |
97 return fReader.readInt(); | |
98 } | |
99 | |
100 void SkOrderedReadBuffer::readString(SkString* string) { | |
101 size_t len; | |
102 const char* strContents = fReader.readString(&len); | |
103 string->set(strContents, len); | |
104 } | |
105 | |
106 void* SkOrderedReadBuffer::readEncodedString(size_t* length, SkPaint::TextEncodi
ng encoding) { | |
107 SkDEBUGCODE(int32_t encodingType = ) fReader.readInt(); | |
108 SkASSERT(encodingType == encoding); | |
109 *length = fReader.readInt(); | |
110 void* data = sk_malloc_throw(*length); | |
111 memcpy(data, fReader.skip(SkAlign4(*length)), *length); | |
112 return data; | |
113 } | |
114 | |
115 void SkOrderedReadBuffer::readPoint(SkPoint* point) { | |
116 point->fX = fReader.readScalar(); | |
117 point->fY = fReader.readScalar(); | |
118 } | |
119 | |
120 void SkOrderedReadBuffer::readMatrix(SkMatrix* matrix) { | |
121 fReader.readMatrix(matrix); | |
122 } | |
123 | |
124 void SkOrderedReadBuffer::readIRect(SkIRect* rect) { | |
125 memcpy(rect, fReader.skip(sizeof(SkIRect)), sizeof(SkIRect)); | |
126 } | |
127 | |
128 void SkOrderedReadBuffer::readRect(SkRect* rect) { | |
129 memcpy(rect, fReader.skip(sizeof(SkRect)), sizeof(SkRect)); | |
130 } | |
131 | |
132 void SkOrderedReadBuffer::readRegion(SkRegion* region) { | |
133 fReader.readRegion(region); | |
134 } | |
135 | |
136 void SkOrderedReadBuffer::readPath(SkPath* path) { | |
137 fReader.readPath(path); | |
138 } | |
139 | |
140 bool SkOrderedReadBuffer::readArray(void* value, size_t size, size_t elementSize
) { | |
141 const size_t count = this->getArrayCount(); | |
142 if (count == size) { | |
143 (void)fReader.skip(sizeof(uint32_t)); // Skip array count | |
144 const size_t byteLength = count * elementSize; | |
145 memcpy(value, fReader.skip(SkAlign4(byteLength)), byteLength); | |
146 return true; | |
147 } | |
148 SkASSERT(false); | |
149 fReader.skip(fReader.available()); | |
150 return false; | |
151 } | |
152 | |
153 bool SkOrderedReadBuffer::readByteArray(void* value, size_t size) { | |
154 return readArray(static_cast<unsigned char*>(value), size, sizeof(unsigned c
har)); | |
155 } | |
156 | |
157 bool SkOrderedReadBuffer::readColorArray(SkColor* colors, size_t size) { | |
158 return readArray(colors, size, sizeof(SkColor)); | |
159 } | |
160 | |
161 bool SkOrderedReadBuffer::readIntArray(int32_t* values, size_t size) { | |
162 return readArray(values, size, sizeof(int32_t)); | |
163 } | |
164 | |
165 bool SkOrderedReadBuffer::readPointArray(SkPoint* points, size_t size) { | |
166 return readArray(points, size, sizeof(SkPoint)); | |
167 } | |
168 | |
169 bool SkOrderedReadBuffer::readScalarArray(SkScalar* values, size_t size) { | |
170 return readArray(values, size, sizeof(SkScalar)); | |
171 } | |
172 | |
173 uint32_t SkOrderedReadBuffer::getArrayCount() { | |
174 return *(uint32_t*)fReader.peek(); | |
175 } | |
176 | |
177 void SkOrderedReadBuffer::readBitmap(SkBitmap* bitmap) { | |
178 const int width = this->readInt(); | |
179 const int height = this->readInt(); | |
180 // The writer stored a boolean value to determine whether an SkBitmapHeap wa
s used during | |
181 // writing. | |
182 if (this->readBool()) { | |
183 // An SkBitmapHeap was used for writing. Read the index from the stream
and find the | |
184 // corresponding SkBitmap in fBitmapStorage. | |
185 const uint32_t index = fReader.readU32(); | |
186 fReader.readU32(); // bitmap generation ID (see SkOrderedWriteBuffer::wr
iteBitmap) | |
187 if (fBitmapStorage) { | |
188 *bitmap = *fBitmapStorage->getBitmap(index); | |
189 fBitmapStorage->releaseRef(index); | |
190 return; | |
191 } else { | |
192 // The bitmap was stored in a heap, but there is no way to access it
. Set an error and | |
193 // fall through to use a place holder bitmap. | |
194 SkErrorInternals::SetError(kParseError_SkError, "SkOrderedWriteBuffe
r::writeBitmap " | |
195 "stored the SkBitmap in an SkBitmapHeap,
but " | |
196 "SkOrderedReadBuffer has no SkBitmapHeapR
eader to " | |
197 "retrieve the SkBitmap."); | |
198 } | |
199 } else { | |
200 // The writer stored false, meaning the SkBitmap was not stored in an Sk
BitmapHeap. | |
201 const size_t length = this->readUInt(); | |
202 if (length > 0) { | |
203 #ifdef DEBUG_NON_DETERMINISTIC_ASSERT | |
204 fDecodedBitmapIndex++; | |
205 #endif // DEBUG_NON_DETERMINISTIC_ASSERT | |
206 // A non-zero size means the SkBitmap was encoded. Read the data and
pixel | |
207 // offset. | |
208 const void* data = this->skip(length); | |
209 const int32_t xOffset = fReader.readS32(); | |
210 const int32_t yOffset = fReader.readS32(); | |
211 if (fBitmapDecoder != NULL && fBitmapDecoder(data, length, bitmap))
{ | |
212 if (bitmap->width() == width && bitmap->height() == height) { | |
213 #ifdef DEBUG_NON_DETERMINISTIC_ASSERT | |
214 if (0 != xOffset || 0 != yOffset) { | |
215 SkDebugf("SkOrderedReadBuffer::readBitmap: heights match
," | |
216 " but offset is not zero. \nInfo about the bitm
ap:" | |
217 "\n\tIndex: %d\n\tDimensions: [%d %d]\n\tEncode
d" | |
218 " data size: %d\n\tOffset: (%d, %d)\n", | |
219 fDecodedBitmapIndex, width, height, length, xOf
fset, | |
220 yOffset); | |
221 } | |
222 #endif // DEBUG_NON_DETERMINISTIC_ASSERT | |
223 // If the width and height match, there should be no offset. | |
224 SkASSERT(0 == xOffset && 0 == yOffset); | |
225 return; | |
226 } | |
227 | |
228 // This case can only be reached if extractSubset was called, so | |
229 // the recorded width and height must be smaller than or equal t
o | |
230 // the encoded width and height. | |
231 // FIXME (scroggo): This assert assumes that our decoder and the | |
232 // sources encoder agree on the width and height which may not | |
233 // always be the case. Removing until it can be investigated | |
234 // further. | |
235 //SkASSERT(width <= bitmap->width() && height <= bitmap->height(
)); | |
236 | |
237 SkBitmap subsetBm; | |
238 SkIRect subset = SkIRect::MakeXYWH(xOffset, yOffset, width, heig
ht); | |
239 if (bitmap->extractSubset(&subsetBm, subset)) { | |
240 bitmap->swap(subsetBm); | |
241 return; | |
242 } | |
243 } | |
244 // This bitmap was encoded when written, but we are unable to decode
, possibly due to | |
245 // not having a decoder. | |
246 SkErrorInternals::SetError(kParseError_SkError, | |
247 "Could not decode bitmap. Resulting bitma
p will be red."); | |
248 } else { | |
249 // A size of zero means the SkBitmap was simply flattened. | |
250 bitmap->unflatten(*this); | |
251 return; | |
252 } | |
253 } | |
254 // Could not read the SkBitmap. Use a placeholder bitmap. | |
255 bitmap->allocPixels(SkImageInfo::MakeN32Premul(width, height)); | |
256 bitmap->eraseColor(SK_ColorRED); | |
257 } | |
258 | |
259 SkTypeface* SkOrderedReadBuffer::readTypeface() { | |
260 | |
261 uint32_t index = fReader.readU32(); | |
262 if (0 == index || index > (unsigned)fTFCount) { | |
263 if (index) { | |
264 SkDebugf("====== typeface index %d\n", index); | |
265 } | |
266 return NULL; | |
267 } else { | |
268 SkASSERT(fTFArray); | |
269 return fTFArray[index - 1]; | |
270 } | |
271 } | |
272 | |
273 SkFlattenable* SkOrderedReadBuffer::readFlattenable(SkFlattenable::Type ft) { | |
274 // | |
275 // TODO: confirm that ft matches the factory we decide to use | |
276 // | |
277 | |
278 SkFlattenable::Factory factory = NULL; | |
279 | |
280 if (fFactoryCount > 0) { | |
281 int32_t index = fReader.readU32(); | |
282 if (0 == index) { | |
283 return NULL; // writer failed to give us the flattenable | |
284 } | |
285 index -= 1; // we stored the index-base-1 | |
286 SkASSERT(index < fFactoryCount); | |
287 factory = fFactoryArray[index]; | |
288 } else if (fFactoryTDArray) { | |
289 int32_t index = fReader.readU32(); | |
290 if (0 == index) { | |
291 return NULL; // writer failed to give us the flattenable | |
292 } | |
293 index -= 1; // we stored the index-base-1 | |
294 factory = (*fFactoryTDArray)[index]; | |
295 } else { | |
296 factory = (SkFlattenable::Factory)readFunctionPtr(); | |
297 if (NULL == factory) { | |
298 return NULL; // writer failed to give us the flattenable | |
299 } | |
300 } | |
301 | |
302 // if we get here, factory may still be null, but if that is the case, the | |
303 // failure was ours, not the writer. | |
304 SkFlattenable* obj = NULL; | |
305 uint32_t sizeRecorded = fReader.readU32(); | |
306 if (factory) { | |
307 uint32_t offset = fReader.offset(); | |
308 obj = (*factory)(*this); | |
309 // check that we read the amount we expected | |
310 uint32_t sizeRead = fReader.offset() - offset; | |
311 if (sizeRecorded != sizeRead) { | |
312 // we could try to fix up the offset... | |
313 sk_throw(); | |
314 } | |
315 } else { | |
316 // we must skip the remaining data | |
317 fReader.skip(sizeRecorded); | |
318 } | |
319 return obj; | |
320 } | |
OLD | NEW |