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