OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2012 Google Inc. | 3 * Copyright 2012 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 #include "SkOrderedWriteBuffer.h" | 9 #include "SkOrderedWriteBuffer.h" |
10 #include "SkBitmap.h" | 10 #include "SkBitmap.h" |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
138 fWriter.reservePad(length - bytesWritten); | 138 fWriter.reservePad(length - bytesWritten); |
139 } | 139 } |
140 return bytesWritten; | 140 return bytesWritten; |
141 } | 141 } |
142 | 142 |
143 bool SkOrderedWriteBuffer::writeToStream(SkWStream* stream) { | 143 bool SkOrderedWriteBuffer::writeToStream(SkWStream* stream) { |
144 return fWriter.writeToStream(stream); | 144 return fWriter.writeToStream(stream); |
145 } | 145 } |
146 | 146 |
147 void SkOrderedWriteBuffer::writeBitmap(const SkBitmap& bitmap) { | 147 void SkOrderedWriteBuffer::writeBitmap(const SkBitmap& bitmap) { |
| 148 // Record the width and height. This way if readBitmap fails a dummy bitmap
can be drawn at the |
| 149 // right size. |
| 150 this->writeInt(bitmap.width()); |
| 151 this->writeInt(bitmap.height()); |
| 152 |
148 // Record information about the bitmap in one of three ways, in order of pri
ority: | 153 // Record information about the bitmap in one of three ways, in order of pri
ority: |
149 // 1. If there is an SkBitmapHeap, store it in the heap. The client can avoi
d serializing the | 154 // 1. If there is an SkBitmapHeap, store it in the heap. The client can avoi
d serializing the |
150 // bitmap entirely or serialize it later as desired. | 155 // bitmap entirely or serialize it later as desired. A boolean value of t
rue will be written |
151 // 2. Write an encoded version of the bitmap. Afterwards the width and heigh
t are written, so | 156 // to the stream to signify that a heap was used. |
152 // a reader without a decoder can draw a dummy bitmap of the right size. | 157 // 2. Write an encoded version of the bitmap. After writing a boolean value
of false, signifying |
| 158 // that a heap was not used, write the size of the encoded data. A non-ze
ro size signifies |
| 159 // that encoded data was written. |
153 // A. If the bitmap has an encoded representation, write it to the stream
. | 160 // A. If the bitmap has an encoded representation, write it to the stream
. |
154 // B. If there is a function for encoding bitmaps, use it. | 161 // B. If there is a function for encoding bitmaps, use it. |
155 // 3. Call SkBitmap::flatten. | 162 // 3. Call SkBitmap::flatten. After writing a boolean value of false, signif
ying that a heap was |
156 // For an encoded bitmap, write the size first. Otherwise store a 0 so the r
eader knows not to | 163 // not used, write a zero to signify that the data was not encoded. |
157 // decode. | 164 bool useBitmapHeap = fBitmapHeap != NULL; |
158 if (fBitmapHeap != NULL) { | 165 // Write a bool: true if the SkBitmapHeap is to be used, in which case the r
eader must use an |
| 166 // SkBitmapHeapReader to read the SkBitmap. False if the bitmap was serializ
ed another way. |
| 167 this->writeBool(useBitmapHeap); |
| 168 if (useBitmapHeap) { |
159 SkASSERT(NULL == fBitmapEncoder); | 169 SkASSERT(NULL == fBitmapEncoder); |
160 // Bitmap was not encoded. Record a zero, implying that the reader need
not decode. | |
161 this->writeUInt(0); | |
162 int32_t slot = fBitmapHeap->insert(bitmap); | 170 int32_t slot = fBitmapHeap->insert(bitmap); |
163 fWriter.write32(slot); | 171 fWriter.write32(slot); |
164 // crbug.com/155875 | 172 // crbug.com/155875 |
165 // The generation ID is not required information. We write it to prevent
collisions | 173 // The generation ID is not required information. We write it to prevent
collisions |
166 // in SkFlatDictionary. It is possible to get a collision when a previo
usly | 174 // in SkFlatDictionary. It is possible to get a collision when a previo
usly |
167 // unflattened (i.e. stale) instance of a similar flattenable is in the
dictionary | 175 // unflattened (i.e. stale) instance of a similar flattenable is in the
dictionary |
168 // and the instance currently being written is re-using the same slot fr
om the | 176 // and the instance currently being written is re-using the same slot fr
om the |
169 // bitmap heap. | 177 // bitmap heap. |
170 fWriter.write32(bitmap.getGenerationID()); | 178 fWriter.write32(bitmap.getGenerationID()); |
171 return; | 179 return; |
172 } | 180 } |
173 bool encoded = false; | 181 bool encoded = false; |
174 // Before attempting to encode the SkBitmap, check to see if there is alread
y an encoded | 182 // Before attempting to encode the SkBitmap, check to see if there is alread
y an encoded |
175 // version. | 183 // version. |
176 SkPixelRef* ref = bitmap.pixelRef(); | 184 SkPixelRef* ref = bitmap.pixelRef(); |
177 if (ref != NULL) { | 185 if (ref != NULL) { |
178 SkAutoDataUnref data(ref->refEncodedData()); | 186 SkAutoDataUnref data(ref->refEncodedData()); |
179 if (data.get() != NULL) { | 187 if (data.get() != NULL) { |
180 // Write the length to indicate that the bitmap was encoded successf
ully, followed | 188 // Write the length to indicate that the bitmap was encoded successf
ully, followed |
181 // by the actual data. This must match the case where fBitmapEncoder
is used so the | 189 // by the actual data. This must match the case where fBitmapEncoder
is used so the |
182 // reader need not know the difference. | 190 // reader need not know the difference. |
183 this->writeUInt(data->size()); | 191 this->writeUInt(SkToU32(data->size())); |
184 fWriter.writePad(data->data(), data->size()); | 192 fWriter.writePad(data->data(), data->size()); |
185 encoded = true; | 193 encoded = true; |
186 } | 194 } |
187 } | 195 } |
188 if (fBitmapEncoder != NULL && !encoded) { | 196 if (fBitmapEncoder != NULL && !encoded) { |
189 SkASSERT(NULL == fBitmapHeap); | 197 SkASSERT(NULL == fBitmapHeap); |
190 SkDynamicMemoryWStream stream; | 198 SkDynamicMemoryWStream stream; |
191 if (fBitmapEncoder(&stream, bitmap)) { | 199 if (fBitmapEncoder(&stream, bitmap)) { |
192 uint32_t offset = fWriter.bytesWritten(); | 200 uint32_t offset = fWriter.bytesWritten(); |
193 // Write the length to indicate that the bitmap was encoded successf
ully, followed | 201 // Write the length to indicate that the bitmap was encoded successf
ully, followed |
194 // by the actual data. This must match the case where the original d
ata is used so the | 202 // by the actual data. This must match the case where the original d
ata is used so the |
195 // reader need not know the difference. | 203 // reader need not know the difference. |
196 size_t length = stream.getOffset(); | 204 size_t length = stream.getOffset(); |
197 this->writeUInt(length); | 205 this->writeUInt(SkToU32(length)); |
198 if (stream.read(fWriter.reservePad(length), 0, length)) { | 206 if (stream.read(fWriter.reservePad(length), 0, length)) { |
199 encoded = true; | 207 encoded = true; |
200 } else { | 208 } else { |
201 // Writing the stream failed, so go back to original state to st
ore another way. | 209 // Writing the stream failed, so go back to original state to st
ore another way. |
202 fWriter.rewindToOffset(offset); | 210 fWriter.rewindToOffset(offset); |
203 } | 211 } |
204 } | 212 } |
205 } | 213 } |
206 if (encoded) { | 214 if (!encoded) { |
207 // Write the width and height in case the reader does not have a decoder
. | |
208 this->writeInt(bitmap.width()); | |
209 this->writeInt(bitmap.height()); | |
210 } else { | |
211 // Bitmap was not encoded. Record a zero, implying that the reader need
not decode. | 215 // Bitmap was not encoded. Record a zero, implying that the reader need
not decode. |
212 this->writeUInt(0); | 216 this->writeUInt(0); |
213 bitmap.flatten(*this); | 217 bitmap.flatten(*this); |
214 } | 218 } |
215 } | 219 } |
216 | 220 |
217 void SkOrderedWriteBuffer::writeTypeface(SkTypeface* obj) { | 221 void SkOrderedWriteBuffer::writeTypeface(SkTypeface* obj) { |
218 if (NULL == obj || NULL == fTFSet) { | 222 if (NULL == obj || NULL == fTFSet) { |
219 fWriter.write32(0); | 223 fWriter.write32(0); |
220 } else { | 224 } else { |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
314 // make room for the size of the flattened object | 318 // make room for the size of the flattened object |
315 (void)fWriter.reserve(sizeof(uint32_t)); | 319 (void)fWriter.reserve(sizeof(uint32_t)); |
316 // record the current size, so we can subtract after the object writes. | 320 // record the current size, so we can subtract after the object writes. |
317 uint32_t offset = fWriter.size(); | 321 uint32_t offset = fWriter.size(); |
318 // now flatten the object | 322 // now flatten the object |
319 flattenObject(flattenable, *this); | 323 flattenObject(flattenable, *this); |
320 uint32_t objSize = fWriter.size() - offset; | 324 uint32_t objSize = fWriter.size() - offset; |
321 // record the obj's size | 325 // record the obj's size |
322 *fWriter.peek32(offset - sizeof(uint32_t)) = objSize; | 326 *fWriter.peek32(offset - sizeof(uint32_t)) = objSize; |
323 } | 327 } |
OLD | NEW |