gfx/skia/trunk/src/core/SkReadBuffer.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/skia/trunk/src/core/SkReadBuffer.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,334 @@
     1.4 +
     1.5 +/*
     1.6 + * Copyright 2012 Google Inc.
     1.7 + *
     1.8 + * Use of this source code is governed by a BSD-style license that can be
     1.9 + * found in the LICENSE file.
    1.10 + */
    1.11 +
    1.12 +#include "SkBitmap.h"
    1.13 +#include "SkErrorInternals.h"
    1.14 +#include "SkReadBuffer.h"
    1.15 +#include "SkStream.h"
    1.16 +#include "SkTypeface.h"
    1.17 +
    1.18 +static uint32_t default_flags() {
    1.19 +    uint32_t flags = 0;
    1.20 +#ifdef SK_SCALAR_IS_FLOAT
    1.21 +    flags |= SkReadBuffer::kScalarIsFloat_Flag;
    1.22 +#endif
    1.23 +    if (8 == sizeof(void*)) {
    1.24 +        flags |= SkReadBuffer::kPtrIs64Bit_Flag;
    1.25 +    }
    1.26 +    return flags;
    1.27 +}
    1.28 +
    1.29 +SkReadBuffer::SkReadBuffer() {
    1.30 +    fFlags = default_flags();
    1.31 +    fMemoryPtr = NULL;
    1.32 +
    1.33 +    fBitmapStorage = NULL;
    1.34 +    fTFArray = NULL;
    1.35 +    fTFCount = 0;
    1.36 +
    1.37 +    fFactoryTDArray = NULL;
    1.38 +    fFactoryArray = NULL;
    1.39 +    fFactoryCount = 0;
    1.40 +    fBitmapDecoder = NULL;
    1.41 +#ifdef DEBUG_NON_DETERMINISTIC_ASSERT
    1.42 +    fDecodedBitmapIndex = -1;
    1.43 +#endif // DEBUG_NON_DETERMINISTIC_ASSERT
    1.44 +}
    1.45 +
    1.46 +SkReadBuffer::SkReadBuffer(const void* data, size_t size) {
    1.47 +    fFlags = default_flags();
    1.48 +    fReader.setMemory(data, size);
    1.49 +    fMemoryPtr = NULL;
    1.50 +
    1.51 +    fBitmapStorage = NULL;
    1.52 +    fTFArray = NULL;
    1.53 +    fTFCount = 0;
    1.54 +
    1.55 +    fFactoryTDArray = NULL;
    1.56 +    fFactoryArray = NULL;
    1.57 +    fFactoryCount = 0;
    1.58 +    fBitmapDecoder = NULL;
    1.59 +#ifdef DEBUG_NON_DETERMINISTIC_ASSERT
    1.60 +    fDecodedBitmapIndex = -1;
    1.61 +#endif // DEBUG_NON_DETERMINISTIC_ASSERT
    1.62 +}
    1.63 +
    1.64 +SkReadBuffer::SkReadBuffer(SkStream* stream) {
    1.65 +    fFlags = default_flags();
    1.66 +    const size_t length = stream->getLength();
    1.67 +    fMemoryPtr = sk_malloc_throw(length);
    1.68 +    stream->read(fMemoryPtr, length);
    1.69 +    fReader.setMemory(fMemoryPtr, length);
    1.70 +
    1.71 +    fBitmapStorage = NULL;
    1.72 +    fTFArray = NULL;
    1.73 +    fTFCount = 0;
    1.74 +
    1.75 +    fFactoryTDArray = NULL;
    1.76 +    fFactoryArray = NULL;
    1.77 +    fFactoryCount = 0;
    1.78 +    fBitmapDecoder = NULL;
    1.79 +#ifdef DEBUG_NON_DETERMINISTIC_ASSERT
    1.80 +    fDecodedBitmapIndex = -1;
    1.81 +#endif // DEBUG_NON_DETERMINISTIC_ASSERT
    1.82 +}
    1.83 +
    1.84 +SkReadBuffer::~SkReadBuffer() {
    1.85 +    sk_free(fMemoryPtr);
    1.86 +    SkSafeUnref(fBitmapStorage);
    1.87 +}
    1.88 +
    1.89 +bool SkReadBuffer::readBool() {
    1.90 +    return fReader.readBool();
    1.91 +}
    1.92 +
    1.93 +SkColor SkReadBuffer::readColor() {
    1.94 +    return fReader.readInt();
    1.95 +}
    1.96 +
    1.97 +SkFixed SkReadBuffer::readFixed() {
    1.98 +    return fReader.readS32();
    1.99 +}
   1.100 +
   1.101 +int32_t SkReadBuffer::readInt() {
   1.102 +    return fReader.readInt();
   1.103 +}
   1.104 +
   1.105 +SkScalar SkReadBuffer::readScalar() {
   1.106 +    return fReader.readScalar();
   1.107 +}
   1.108 +
   1.109 +uint32_t SkReadBuffer::readUInt() {
   1.110 +    return fReader.readU32();
   1.111 +}
   1.112 +
   1.113 +int32_t SkReadBuffer::read32() {
   1.114 +    return fReader.readInt();
   1.115 +}
   1.116 +
   1.117 +void SkReadBuffer::readString(SkString* string) {
   1.118 +    size_t len;
   1.119 +    const char* strContents = fReader.readString(&len);
   1.120 +    string->set(strContents, len);
   1.121 +}
   1.122 +
   1.123 +void* SkReadBuffer::readEncodedString(size_t* length, SkPaint::TextEncoding encoding) {
   1.124 +    SkDEBUGCODE(int32_t encodingType = ) fReader.readInt();
   1.125 +    SkASSERT(encodingType == encoding);
   1.126 +    *length =  fReader.readInt();
   1.127 +    void* data = sk_malloc_throw(*length);
   1.128 +    memcpy(data, fReader.skip(SkAlign4(*length)), *length);
   1.129 +    return data;
   1.130 +}
   1.131 +
   1.132 +void SkReadBuffer::readPoint(SkPoint* point) {
   1.133 +    point->fX = fReader.readScalar();
   1.134 +    point->fY = fReader.readScalar();
   1.135 +}
   1.136 +
   1.137 +void SkReadBuffer::readMatrix(SkMatrix* matrix) {
   1.138 +    fReader.readMatrix(matrix);
   1.139 +}
   1.140 +
   1.141 +void SkReadBuffer::readIRect(SkIRect* rect) {
   1.142 +    memcpy(rect, fReader.skip(sizeof(SkIRect)), sizeof(SkIRect));
   1.143 +}
   1.144 +
   1.145 +void SkReadBuffer::readRect(SkRect* rect) {
   1.146 +    memcpy(rect, fReader.skip(sizeof(SkRect)), sizeof(SkRect));
   1.147 +}
   1.148 +
   1.149 +void SkReadBuffer::readRegion(SkRegion* region) {
   1.150 +    fReader.readRegion(region);
   1.151 +}
   1.152 +
   1.153 +void SkReadBuffer::readPath(SkPath* path) {
   1.154 +    fReader.readPath(path);
   1.155 +}
   1.156 +
   1.157 +bool SkReadBuffer::readArray(void* value, size_t size, size_t elementSize) {
   1.158 +    const size_t count = this->getArrayCount();
   1.159 +    if (count == size) {
   1.160 +        (void)fReader.skip(sizeof(uint32_t)); // Skip array count
   1.161 +        const size_t byteLength = count * elementSize;
   1.162 +        memcpy(value, fReader.skip(SkAlign4(byteLength)), byteLength);
   1.163 +        return true;
   1.164 +    }
   1.165 +    SkASSERT(false);
   1.166 +    fReader.skip(fReader.available());
   1.167 +    return false;
   1.168 +}
   1.169 +
   1.170 +bool SkReadBuffer::readByteArray(void* value, size_t size) {
   1.171 +    return readArray(static_cast<unsigned char*>(value), size, sizeof(unsigned char));
   1.172 +}
   1.173 +
   1.174 +bool SkReadBuffer::readColorArray(SkColor* colors, size_t size) {
   1.175 +    return readArray(colors, size, sizeof(SkColor));
   1.176 +}
   1.177 +
   1.178 +bool SkReadBuffer::readIntArray(int32_t* values, size_t size) {
   1.179 +    return readArray(values, size, sizeof(int32_t));
   1.180 +}
   1.181 +
   1.182 +bool SkReadBuffer::readPointArray(SkPoint* points, size_t size) {
   1.183 +    return readArray(points, size, sizeof(SkPoint));
   1.184 +}
   1.185 +
   1.186 +bool SkReadBuffer::readScalarArray(SkScalar* values, size_t size) {
   1.187 +    return readArray(values, size, sizeof(SkScalar));
   1.188 +}
   1.189 +
   1.190 +uint32_t SkReadBuffer::getArrayCount() {
   1.191 +    return *(uint32_t*)fReader.peek();
   1.192 +}
   1.193 +
   1.194 +void SkReadBuffer::readBitmap(SkBitmap* bitmap) {
   1.195 +    const int width = this->readInt();
   1.196 +    const int height = this->readInt();
   1.197 +    // The writer stored a boolean value to determine whether an SkBitmapHeap was used during
   1.198 +    // writing.
   1.199 +    if (this->readBool()) {
   1.200 +        // An SkBitmapHeap was used for writing. Read the index from the stream and find the
   1.201 +        // corresponding SkBitmap in fBitmapStorage.
   1.202 +        const uint32_t index = fReader.readU32();
   1.203 +        fReader.readU32(); // bitmap generation ID (see SkWriteBuffer::writeBitmap)
   1.204 +        if (fBitmapStorage) {
   1.205 +            *bitmap = *fBitmapStorage->getBitmap(index);
   1.206 +            fBitmapStorage->releaseRef(index);
   1.207 +            return;
   1.208 +        } else {
   1.209 +            // The bitmap was stored in a heap, but there is no way to access it. Set an error and
   1.210 +            // fall through to use a place holder bitmap.
   1.211 +            SkErrorInternals::SetError(kParseError_SkError, "SkWriteBuffer::writeBitmap "
   1.212 +                                       "stored the SkBitmap in an SkBitmapHeap, but "
   1.213 +                                       "SkReadBuffer has no SkBitmapHeapReader to "
   1.214 +                                       "retrieve the SkBitmap.");
   1.215 +        }
   1.216 +    } else {
   1.217 +        // The writer stored false, meaning the SkBitmap was not stored in an SkBitmapHeap.
   1.218 +        const size_t length = this->readUInt();
   1.219 +        if (length > 0) {
   1.220 +#ifdef DEBUG_NON_DETERMINISTIC_ASSERT
   1.221 +            fDecodedBitmapIndex++;
   1.222 +#endif // DEBUG_NON_DETERMINISTIC_ASSERT
   1.223 +            // A non-zero size means the SkBitmap was encoded. Read the data and pixel
   1.224 +            // offset.
   1.225 +            const void* data = this->skip(length);
   1.226 +            const int32_t xOffset = fReader.readS32();
   1.227 +            const int32_t yOffset = fReader.readS32();
   1.228 +            if (fBitmapDecoder != NULL && fBitmapDecoder(data, length, bitmap)) {
   1.229 +                if (bitmap->width() == width && bitmap->height() == height) {
   1.230 +#ifdef DEBUG_NON_DETERMINISTIC_ASSERT
   1.231 +                    if (0 != xOffset || 0 != yOffset) {
   1.232 +                        SkDebugf("SkReadBuffer::readBitmap: heights match,"
   1.233 +                                 " but offset is not zero. \nInfo about the bitmap:"
   1.234 +                                 "\n\tIndex: %d\n\tDimensions: [%d %d]\n\tEncoded"
   1.235 +                                 " data size: %d\n\tOffset: (%d, %d)\n",
   1.236 +                                 fDecodedBitmapIndex, width, height, length, xOffset,
   1.237 +                                 yOffset);
   1.238 +                    }
   1.239 +#endif // DEBUG_NON_DETERMINISTIC_ASSERT
   1.240 +                    // If the width and height match, there should be no offset.
   1.241 +                    SkASSERT(0 == xOffset && 0 == yOffset);
   1.242 +                    return;
   1.243 +                }
   1.244 +
   1.245 +                // This case can only be reached if extractSubset was called, so
   1.246 +                // the recorded width and height must be smaller than or equal to
   1.247 +                // the encoded width and height.
   1.248 +                // FIXME (scroggo): This assert assumes that our decoder and the
   1.249 +                // sources encoder agree on the width and height which may not
   1.250 +                // always be the case. Removing until it can be investigated
   1.251 +                // further.
   1.252 +                //SkASSERT(width <= bitmap->width() && height <= bitmap->height());
   1.253 +
   1.254 +                SkBitmap subsetBm;
   1.255 +                SkIRect subset = SkIRect::MakeXYWH(xOffset, yOffset, width, height);
   1.256 +                if (bitmap->extractSubset(&subsetBm, subset)) {
   1.257 +                    bitmap->swap(subsetBm);
   1.258 +                    return;
   1.259 +                }
   1.260 +            }
   1.261 +            // This bitmap was encoded when written, but we are unable to decode, possibly due to
   1.262 +            // not having a decoder.
   1.263 +            SkErrorInternals::SetError(kParseError_SkError,
   1.264 +                                       "Could not decode bitmap. Resulting bitmap will be red.");
   1.265 +        } else {
   1.266 +            // A size of zero means the SkBitmap was simply flattened.
   1.267 +            bitmap->unflatten(*this);
   1.268 +            return;
   1.269 +        }
   1.270 +    }
   1.271 +    // Could not read the SkBitmap. Use a placeholder bitmap.
   1.272 +    bitmap->allocPixels(SkImageInfo::MakeN32Premul(width, height));
   1.273 +    bitmap->eraseColor(SK_ColorRED);
   1.274 +}
   1.275 +
   1.276 +SkTypeface* SkReadBuffer::readTypeface() {
   1.277 +
   1.278 +    uint32_t index = fReader.readU32();
   1.279 +    if (0 == index || index > (unsigned)fTFCount) {
   1.280 +        if (index) {
   1.281 +            SkDebugf("====== typeface index %d\n", index);
   1.282 +        }
   1.283 +        return NULL;
   1.284 +    } else {
   1.285 +        SkASSERT(fTFArray);
   1.286 +        return fTFArray[index - 1];
   1.287 +    }
   1.288 +}
   1.289 +
   1.290 +SkFlattenable* SkReadBuffer::readFlattenable(SkFlattenable::Type ft) {
   1.291 +    //
   1.292 +    // TODO: confirm that ft matches the factory we decide to use
   1.293 +    //
   1.294 +
   1.295 +    SkFlattenable::Factory factory = NULL;
   1.296 +
   1.297 +    if (fFactoryCount > 0) {
   1.298 +        int32_t index = fReader.readU32();
   1.299 +        if (0 == index) {
   1.300 +            return NULL; // writer failed to give us the flattenable
   1.301 +        }
   1.302 +        index -= 1;     // we stored the index-base-1
   1.303 +        SkASSERT(index < fFactoryCount);
   1.304 +        factory = fFactoryArray[index];
   1.305 +    } else if (fFactoryTDArray) {
   1.306 +        int32_t index = fReader.readU32();
   1.307 +        if (0 == index) {
   1.308 +            return NULL; // writer failed to give us the flattenable
   1.309 +        }
   1.310 +        index -= 1;     // we stored the index-base-1
   1.311 +        factory = (*fFactoryTDArray)[index];
   1.312 +    } else {
   1.313 +        factory = (SkFlattenable::Factory)readFunctionPtr();
   1.314 +        if (NULL == factory) {
   1.315 +            return NULL; // writer failed to give us the flattenable
   1.316 +        }
   1.317 +    }
   1.318 +
   1.319 +    // if we get here, factory may still be null, but if that is the case, the
   1.320 +    // failure was ours, not the writer.
   1.321 +    SkFlattenable* obj = NULL;
   1.322 +    uint32_t sizeRecorded = fReader.readU32();
   1.323 +    if (factory) {
   1.324 +        uint32_t offset = fReader.offset();
   1.325 +        obj = (*factory)(*this);
   1.326 +        // check that we read the amount we expected
   1.327 +        uint32_t sizeRead = fReader.offset() - offset;
   1.328 +        if (sizeRecorded != sizeRead) {
   1.329 +            // we could try to fix up the offset...
   1.330 +            sk_throw();
   1.331 +        }
   1.332 +    } else {
   1.333 +        // we must skip the remaining data
   1.334 +        fReader.skip(sizeRecorded);
   1.335 +    }
   1.336 +    return obj;
   1.337 +}

mercurial