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" |
11 #include "SkData.h" | 11 #include "SkData.h" |
12 #include "SkPixelRef.h" | |
13 #include "SkPtrRecorder.h" | 12 #include "SkPtrRecorder.h" |
14 #include "SkStream.h" | 13 #include "SkStream.h" |
15 #include "SkTypeface.h" | 14 #include "SkTypeface.h" |
16 | 15 |
17 SkOrderedWriteBuffer::SkOrderedWriteBuffer(size_t minSize) | 16 SkOrderedWriteBuffer::SkOrderedWriteBuffer(size_t minSize) |
18 : INHERITED() | 17 : INHERITED() |
19 , fFactorySet(NULL) | 18 , fFactorySet(NULL) |
20 , fNamedFactorySet(NULL) | 19 , fNamedFactorySet(NULL) |
21 , fWriter(minSize) | 20 , fWriter(minSize) |
22 , fBitmapHeap(NULL) | 21 , fBitmapHeap(NULL) |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
137 if (bytesWritten < length) { | 136 if (bytesWritten < length) { |
138 fWriter.reservePad(length - bytesWritten); | 137 fWriter.reservePad(length - bytesWritten); |
139 } | 138 } |
140 return bytesWritten; | 139 return bytesWritten; |
141 } | 140 } |
142 | 141 |
143 bool SkOrderedWriteBuffer::writeToStream(SkWStream* stream) { | 142 bool SkOrderedWriteBuffer::writeToStream(SkWStream* stream) { |
144 return fWriter.writeToStream(stream); | 143 return fWriter.writeToStream(stream); |
145 } | 144 } |
146 | 145 |
| 146 // Defined in SkBitmap.cpp |
| 147 bool get_upper_left_from_offset(SkBitmap::Config config, size_t offset, size_t r
owBytes, |
| 148 int32_t* x, int32_t* y); |
| 149 |
147 void SkOrderedWriteBuffer::writeBitmap(const SkBitmap& bitmap) { | 150 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 | 151 // Record the width and height. This way if readBitmap fails a dummy bitmap
can be drawn at the |
149 // right size. | 152 // right size. |
150 this->writeInt(bitmap.width()); | 153 this->writeInt(bitmap.width()); |
151 this->writeInt(bitmap.height()); | 154 this->writeInt(bitmap.height()); |
152 | 155 |
153 // Record information about the bitmap in one of three ways, in order of pri
ority: | 156 // Record information about the bitmap in one of three ways, in order of pri
ority: |
154 // 1. If there is an SkBitmapHeap, store it in the heap. The client can avoi
d serializing the | 157 // 1. If there is an SkBitmapHeap, store it in the heap. The client can avoi
d serializing the |
155 // bitmap entirely or serialize it later as desired. A boolean value of t
rue will be written | 158 // bitmap entirely or serialize it later as desired. A boolean value of t
rue will be written |
156 // to the stream to signify that a heap was used. | 159 // to the stream to signify that a heap was used. |
157 // 2. Write an encoded version of the bitmap. After writing a boolean value
of false, signifying | 160 // 2. If there is a function for encoding bitmaps, use it to write an encode
d version of the |
158 // that a heap was not used, write the size of the encoded data. A non-ze
ro size signifies | 161 // bitmap. After writing a boolean value of false, signifying that a heap
was not used, write |
159 // that encoded data was written. | 162 // the size of the encoded data. A non-zero size signifies that encoded d
ata was written. |
160 // A. If the bitmap has an encoded representation, write it to the stream
. | |
161 // B. If there is a function for encoding bitmaps, use it. | |
162 // 3. Call SkBitmap::flatten. After writing a boolean value of false, signif
ying that a heap was | 163 // 3. Call SkBitmap::flatten. After writing a boolean value of false, signif
ying that a heap was |
163 // not used, write a zero to signify that the data was not encoded. | 164 // not used, write a zero to signify that the data was not encoded. |
164 bool useBitmapHeap = fBitmapHeap != NULL; | 165 bool useBitmapHeap = fBitmapHeap != NULL; |
165 // Write a bool: true if the SkBitmapHeap is to be used, in which case the r
eader must use an | 166 // 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 // SkBitmapHeapReader to read the SkBitmap. False if the bitmap was serializ
ed another way. |
167 this->writeBool(useBitmapHeap); | 168 this->writeBool(useBitmapHeap); |
168 if (useBitmapHeap) { | 169 if (useBitmapHeap) { |
169 SkASSERT(NULL == fBitmapEncoder); | 170 SkASSERT(NULL == fBitmapEncoder); |
170 int32_t slot = fBitmapHeap->insert(bitmap); | 171 int32_t slot = fBitmapHeap->insert(bitmap); |
171 fWriter.write32(slot); | 172 fWriter.write32(slot); |
172 // crbug.com/155875 | 173 // crbug.com/155875 |
173 // The generation ID is not required information. We write it to prevent
collisions | 174 // The generation ID is not required information. We write it to prevent
collisions |
174 // in SkFlatDictionary. It is possible to get a collision when a previo
usly | 175 // in SkFlatDictionary. It is possible to get a collision when a previo
usly |
175 // unflattened (i.e. stale) instance of a similar flattenable is in the
dictionary | 176 // unflattened (i.e. stale) instance of a similar flattenable is in the
dictionary |
176 // and the instance currently being written is re-using the same slot fr
om the | 177 // and the instance currently being written is re-using the same slot fr
om the |
177 // bitmap heap. | 178 // bitmap heap. |
178 fWriter.write32(bitmap.getGenerationID()); | 179 fWriter.write32(bitmap.getGenerationID()); |
179 return; | 180 return; |
180 } | 181 } |
181 bool encoded = false; | 182 if (fBitmapEncoder != NULL) { |
182 // Before attempting to encode the SkBitmap, check to see if there is alread
y an encoded | 183 SkASSERT(NULL == fBitmapHeap); |
183 // version. | 184 size_t offset; |
184 SkPixelRef* ref = bitmap.pixelRef(); | 185 SkAutoDataUnref data(fBitmapEncoder(&offset, bitmap)); |
185 if (ref != NULL) { | |
186 SkAutoDataUnref data(ref->refEncodedData()); | |
187 if (data.get() != NULL) { | 186 if (data.get() != NULL) { |
188 // Write the length to indicate that the bitmap was encoded successf
ully, followed | 187 // Write the length to indicate that the bitmap was encoded successf
ully, followed |
189 // by the actual data. This must match the case where fBitmapEncoder
is used so the | 188 // by the actual data. |
190 // reader need not know the difference. | |
191 this->writeUInt(SkToU32(data->size())); | 189 this->writeUInt(SkToU32(data->size())); |
192 fWriter.writePad(data->data(), data->size()); | 190 fWriter.writePad(data->data(), data->size()); |
193 encoded = true; | 191 #ifdef BUMP_PICTURE_VERSION |
| 192 // Recording this fixes https://code.google.com/p/skia/issues/detail
?id=1301, but |
| 193 // also requires bumping PICTURE_VERSION, so leaving out for now. |
| 194 // Store the coordinate of the offset, rather than fPixelRefOffset,
which may be |
| 195 // different depending on the decoder. |
| 196 int32_t x, y; |
| 197 if (0 == offset || !get_upper_left_from_offset(bitmap.config(), offs
et, |
| 198 bitmap.rowBytes(), &x
, &y)) { |
| 199 x = y = 0; |
| 200 } |
| 201 this->write32(x); |
| 202 this->write32(y); |
| 203 #endif |
| 204 return; |
194 } | 205 } |
195 } | 206 } |
196 if (fBitmapEncoder != NULL && !encoded) { | 207 // Bitmap was not encoded. Record a zero, implying that the reader need not
decode. |
197 SkASSERT(NULL == fBitmapHeap); | 208 this->writeUInt(0); |
198 SkDynamicMemoryWStream stream; | 209 bitmap.flatten(*this); |
199 if (fBitmapEncoder(&stream, bitmap)) { | |
200 uint32_t offset = fWriter.bytesWritten(); | |
201 // Write the length to indicate that the bitmap was encoded successf
ully, followed | |
202 // by the actual data. This must match the case where the original d
ata is used so the | |
203 // reader need not know the difference. | |
204 size_t length = stream.getOffset(); | |
205 this->writeUInt(SkToU32(length)); | |
206 if (stream.read(fWriter.reservePad(length), 0, length)) { | |
207 encoded = true; | |
208 } else { | |
209 // Writing the stream failed, so go back to original state to st
ore another way. | |
210 fWriter.rewindToOffset(offset); | |
211 } | |
212 } | |
213 } | |
214 if (!encoded) { | |
215 // Bitmap was not encoded. Record a zero, implying that the reader need
not decode. | |
216 this->writeUInt(0); | |
217 bitmap.flatten(*this); | |
218 } | |
219 } | 210 } |
220 | 211 |
221 void SkOrderedWriteBuffer::writeTypeface(SkTypeface* obj) { | 212 void SkOrderedWriteBuffer::writeTypeface(SkTypeface* obj) { |
222 if (NULL == obj || NULL == fTFSet) { | 213 if (NULL == obj || NULL == fTFSet) { |
223 fWriter.write32(0); | 214 fWriter.write32(0); |
224 } else { | 215 } else { |
225 fWriter.write32(fTFSet->add(obj)); | 216 fWriter.write32(fTFSet->add(obj)); |
226 } | 217 } |
227 } | 218 } |
228 | 219 |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
318 // make room for the size of the flattened object | 309 // make room for the size of the flattened object |
319 (void)fWriter.reserve(sizeof(uint32_t)); | 310 (void)fWriter.reserve(sizeof(uint32_t)); |
320 // record the current size, so we can subtract after the object writes. | 311 // record the current size, so we can subtract after the object writes. |
321 uint32_t offset = fWriter.size(); | 312 uint32_t offset = fWriter.size(); |
322 // now flatten the object | 313 // now flatten the object |
323 flattenObject(flattenable, *this); | 314 flattenObject(flattenable, *this); |
324 uint32_t objSize = fWriter.size() - offset; | 315 uint32_t objSize = fWriter.size() - offset; |
325 // record the obj's size | 316 // record the obj's size |
326 *fWriter.peek32(offset - sizeof(uint32_t)) = objSize; | 317 *fWriter.peek32(offset - sizeof(uint32_t)) = objSize; |
327 } | 318 } |
OLD | NEW |