1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */
7bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com
849099b25367d1b9ef45ccaa7fe370facea6b89bfreed@android.com#include "SkMallocPixelRef.h"
949099b25367d1b9ef45ccaa7fe370facea6b89bfreed@android.com#include "SkBitmap.h"
108b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkReadBuffer.h"
118b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkWriteBuffer.h"
1249099b25367d1b9ef45ccaa7fe370facea6b89bfreed@android.com
131bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com// assumes ptr was allocated via sk_malloc
141bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.comstatic void sk_free_releaseproc(void* ptr, void*) {
151bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com    sk_free(ptr);
161bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com}
171bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com
18bf790232f6d94b54239dbc210d8beee7411ca458reed@google.comstatic bool is_valid(const SkImageInfo& info, SkColorTable* ctable) {
19bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    if (info.fWidth < 0 ||
20bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        info.fHeight < 0 ||
21bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        (unsigned)info.fColorType > (unsigned)kLastEnum_SkColorType ||
22bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        (unsigned)info.fAlphaType > (unsigned)kLastEnum_SkAlphaType)
23bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    {
24bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        return false;
25bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    }
2696f5fa02e996e39179f2eb88d57e8ed6114b06c5skia.committer@gmail.com
27bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    // these seem like good checks, but currently we have (at least) tests
28bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    // that expect the pixelref to succeed even when there is a mismatch
29bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    // with colortables. fix?
30bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com#if 0
31bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    if (kIndex8_SkColorType == info.fColorType && NULL == ctable) {
32bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        return false;
33bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    }
34bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    if (kIndex8_SkColorType != info.fColorType && NULL != ctable) {
35bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        return false;
36bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    }
37bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com#endif
38bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    return true;
39bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com}
40bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com
41bf790232f6d94b54239dbc210d8beee7411ca458reed@google.comSkMallocPixelRef* SkMallocPixelRef::NewDirect(const SkImageInfo& info,
42bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com                                              void* addr,
43bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com                                              size_t rowBytes,
44bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com                                              SkColorTable* ctable) {
45bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    if (!is_valid(info, ctable)) {
46bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        return NULL;
47bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    }
481bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com    return SkNEW_ARGS(SkMallocPixelRef,
491bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com                      (info, addr, rowBytes, ctable, NULL, NULL));
50bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com}
51bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com
522c4e75cc3c0302e0e151d90c74b4c476bfa8a8b5commit-bot@chromium.org
53bf790232f6d94b54239dbc210d8beee7411ca458reed@google.comSkMallocPixelRef* SkMallocPixelRef::NewAllocate(const SkImageInfo& info,
54bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com                                                size_t requestedRowBytes,
55bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com                                                SkColorTable* ctable) {
56bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    if (!is_valid(info, ctable)) {
57bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        return NULL;
58bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    }
59bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com
60a8c7f7702fb4bbedb615031bc653c5cd161a038ecommit-bot@chromium.org    int32_t minRB = SkToS32(info.minRowBytes());
61bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    if (minRB < 0) {
62bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        return NULL;    // allocation will be too large
63bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    }
64bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    if (requestedRowBytes > 0 && (int32_t)requestedRowBytes < minRB) {
65bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        return NULL;    // cannot meet requested rowbytes
66bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    }
67bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com
68bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    int32_t rowBytes;
69bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    if (requestedRowBytes) {
70a8c7f7702fb4bbedb615031bc653c5cd161a038ecommit-bot@chromium.org        rowBytes = SkToS32(requestedRowBytes);
71bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    } else {
72bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        rowBytes = minRB;
7349099b25367d1b9ef45ccaa7fe370facea6b89bfreed@android.com    }
74bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com
7557212f9469c8056bab3c85243dbb904e386eab95reed@google.com    int64_t bigSize = (int64_t)info.fHeight * rowBytes;
7657212f9469c8056bab3c85243dbb904e386eab95reed@google.com    if (!sk_64_isS32(bigSize)) {
77bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        return NULL;
78bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    }
79bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com
8057212f9469c8056bab3c85243dbb904e386eab95reed@google.com    size_t size = sk_64_asS32(bigSize);
811bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com    SkASSERT(size >= info.getSafeSize(rowBytes));
82bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    void* addr = sk_malloc_flags(size, 0);
83bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    if (NULL == addr) {
84bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        return NULL;
85bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    }
86bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com
871bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com    return SkNEW_ARGS(SkMallocPixelRef,
881bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com                      (info, addr, rowBytes, ctable,
891bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com                       sk_free_releaseproc, NULL));
901bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com}
911bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com
921bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.comSkMallocPixelRef* SkMallocPixelRef::NewWithProc(const SkImageInfo& info,
931bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com                                                size_t rowBytes,
941bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com                                                SkColorTable* ctable,
951bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com                                                void* addr,
961bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com                                                SkMallocPixelRef::ReleaseProc proc,
971bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com                                                void* context) {
981bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com    if (!is_valid(info, ctable)) {
991bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com        return NULL;
1001bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com    }
1011bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com    return SkNEW_ARGS(SkMallocPixelRef,
1021bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com                      (info, addr, rowBytes, ctable, proc, context));
1031bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com}
1041bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com
1051bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.comstatic void sk_data_releaseproc(void*, void* dataPtr) {
1061bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com    (static_cast<SkData*>(dataPtr))->unref();
1071bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com}
1081bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com
1091bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.comSkMallocPixelRef* SkMallocPixelRef::NewWithData(const SkImageInfo& info,
1101bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com                                                size_t rowBytes,
1111bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com                                                SkColorTable* ctable,
1122c4e75cc3c0302e0e151d90c74b4c476bfa8a8b5commit-bot@chromium.org                                                SkData* data) {
1131bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com    SkASSERT(data != NULL);
1141bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com    if (!is_valid(info, ctable)) {
1151bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com        return NULL;
1161bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com    }
1171bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com    if ((rowBytes < info.minRowBytes())
1182c4e75cc3c0302e0e151d90c74b4c476bfa8a8b5commit-bot@chromium.org        || (data->size() < info.getSafeSize(rowBytes))) {
1191bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com        return NULL;
1201bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com    }
1211bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com    data->ref();
1221bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com    SkMallocPixelRef* pr
1231bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com        = SkNEW_ARGS(SkMallocPixelRef,
1242c4e75cc3c0302e0e151d90c74b4c476bfa8a8b5commit-bot@chromium.org                     (info, const_cast<void*>(data->data()), rowBytes, ctable,
1251bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com                      sk_data_releaseproc, static_cast<void*>(data)));
1261bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com    SkASSERT(pr != NULL);
1271bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com    // We rely on the immutability of the pixels to make the
1281bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com    // const_cast okay.
1291bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com    pr->setImmutable();
1301bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com    return pr;
131bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com}
132bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com
133bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com///////////////////////////////////////////////////////////////////////////////
134bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com
135bf790232f6d94b54239dbc210d8beee7411ca458reed@google.comSkMallocPixelRef::SkMallocPixelRef(const SkImageInfo& info, void* storage,
136bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com                                   size_t rowBytes, SkColorTable* ctable,
137bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com                                   bool ownsPixels)
138bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    : INHERITED(info)
1391bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com    , fReleaseProc(ownsPixels ? sk_free_releaseproc : NULL)
1401bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com    , fReleaseProcContext(NULL) {
1411bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com    // This constructor is now DEPRICATED.
1421bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com    SkASSERT(is_valid(info, ctable));
1431bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com    SkASSERT(rowBytes >= info.minRowBytes());
1441bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com
1451bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com    if (kIndex_8_SkColorType != info.fColorType) {
1461bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com        ctable = NULL;
1471bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com    }
1481bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com
1491bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com    fStorage = storage;
1501bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com    fCTable = ctable;
1511bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com    fRB = rowBytes;
1521bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com    SkSafeRef(ctable);
1531bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com
1547627c657b039ea9aa2a01a7d74e652fe7e27def4reed@google.com    this->setPreLocked(fStorage, rowBytes, fCTable);
1551bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com}
1561bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com
1571bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.comSkMallocPixelRef::SkMallocPixelRef(const SkImageInfo& info, void* storage,
1581bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com                                   size_t rowBytes, SkColorTable* ctable,
1591bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com                                   SkMallocPixelRef::ReleaseProc proc,
1601bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com                                   void* context)
1611bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com    : INHERITED(info)
1621bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com    , fReleaseProc(proc)
1631bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com    , fReleaseProcContext(context)
164bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com{
165bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    SkASSERT(is_valid(info, ctable));
166bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    SkASSERT(rowBytes >= info.minRowBytes());
167bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com
168bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    if (kIndex_8_SkColorType != info.fColorType) {
169bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com        ctable = NULL;
170bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    }
171bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com
17249099b25367d1b9ef45ccaa7fe370facea6b89bfreed@android.com    fStorage = storage;
17349099b25367d1b9ef45ccaa7fe370facea6b89bfreed@android.com    fCTable = ctable;
174bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    fRB = rowBytes;
17582065d667f64e232bcde2ad849756a6096fcbe6freed@google.com    SkSafeRef(ctable);
17698272d91421c52211e0e0137f494c1cad01c3c68skia.committer@gmail.com
1777627c657b039ea9aa2a01a7d74e652fe7e27def4reed@google.com    this->setPreLocked(fStorage, rowBytes, fCTable);
17849099b25367d1b9ef45ccaa7fe370facea6b89bfreed@android.com}
17949099b25367d1b9ef45ccaa7fe370facea6b89bfreed@android.com
1801bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com
18149099b25367d1b9ef45ccaa7fe370facea6b89bfreed@android.comSkMallocPixelRef::~SkMallocPixelRef() {
18249099b25367d1b9ef45ccaa7fe370facea6b89bfreed@android.com    SkSafeUnref(fCTable);
1831bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com    if (fReleaseProc != NULL) {
1841bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com        fReleaseProc(fStorage, fReleaseProcContext);
185c84b8335ee4fd864c30a4703afc643cf4b5010d9djsollen@google.com    }
18649099b25367d1b9ef45ccaa7fe370facea6b89bfreed@android.com}
18749099b25367d1b9ef45ccaa7fe370facea6b89bfreed@android.com
188d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.combool SkMallocPixelRef::onNewLockPixels(LockRec* rec) {
189d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com    rec->fPixels = fStorage;
190d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com    rec->fRowBytes = fRB;
191d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com    rec->fColorTable = fCTable;
192d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com    return true;
19349099b25367d1b9ef45ccaa7fe370facea6b89bfreed@android.com}
19449099b25367d1b9ef45ccaa7fe370facea6b89bfreed@android.com
19549099b25367d1b9ef45ccaa7fe370facea6b89bfreed@android.comvoid SkMallocPixelRef::onUnlockPixels() {
19649099b25367d1b9ef45ccaa7fe370facea6b89bfreed@android.com    // nothing to do
19749099b25367d1b9ef45ccaa7fe370facea6b89bfreed@android.com}
19849099b25367d1b9ef45ccaa7fe370facea6b89bfreed@android.com
199bf790232f6d94b54239dbc210d8beee7411ca458reed@google.comsize_t SkMallocPixelRef::getAllocatedSizeInBytes() const {
200bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    return this->info().getSafeSize(fRB);
201bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com}
202bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com
2038b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgvoid SkMallocPixelRef::flatten(SkWriteBuffer& buffer) const {
20449099b25367d1b9ef45ccaa7fe370facea6b89bfreed@android.com    this->INHERITED::flatten(buffer);
20549099b25367d1b9ef45ccaa7fe370facea6b89bfreed@android.com
206a8c7f7702fb4bbedb615031bc653c5cd161a038ecommit-bot@chromium.org    buffer.write32(SkToU32(fRB));
207bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com
208bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    // TODO: replace this bulk write with a chunky one that can trim off any
209bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    // trailing bytes on each scanline (in case rowbytes > width*size)
210bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    size_t size = this->info().getSafeSize(fRB);
211bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    buffer.writeByteArray(fStorage, size);
212c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com    buffer.writeBool(fCTable != NULL);
21349099b25367d1b9ef45ccaa7fe370facea6b89bfreed@android.com    if (fCTable) {
214e0e1da34f3c00ec93c61643d4cf4eea6d27c5fefcommit-bot@chromium.org        fCTable->writeToBuffer(buffer);
21549099b25367d1b9ef45ccaa7fe370facea6b89bfreed@android.com    }
21649099b25367d1b9ef45ccaa7fe370facea6b89bfreed@android.com}
21749099b25367d1b9ef45ccaa7fe370facea6b89bfreed@android.com
2188b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgSkMallocPixelRef::SkMallocPixelRef(SkReadBuffer& buffer)
219bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    : INHERITED(buffer, NULL)
2201bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com    , fReleaseProc(sk_free_releaseproc)
2211bed687f6b8fc67336f0f5d6fb5a5b38dd0fdff9halcanary@google.com    , fReleaseProcContext(NULL)
222bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com{
223bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    fRB = buffer.read32();
224fbd9b17711e6f86853f1c5fdb76efce1b9f52bd1commit-bot@chromium.org    size_t size = buffer.isValid() ? this->info().getSafeSize(fRB) : 0;
225ef74fa189b738e13295d6a96f86a6e10223505a8commit-bot@chromium.org    if (buffer.validateAvailable(size)) {
226ef74fa189b738e13295d6a96f86a6e10223505a8commit-bot@chromium.org        fStorage = sk_malloc_throw(size);
227ef74fa189b738e13295d6a96f86a6e10223505a8commit-bot@chromium.org        buffer.readByteArray(fStorage, size);
228ef74fa189b738e13295d6a96f86a6e10223505a8commit-bot@chromium.org    } else {
229ef74fa189b738e13295d6a96f86a6e10223505a8commit-bot@chromium.org        fStorage = NULL;
230ef74fa189b738e13295d6a96f86a6e10223505a8commit-bot@chromium.org    }
231ef74fa189b738e13295d6a96f86a6e10223505a8commit-bot@chromium.org
23249099b25367d1b9ef45ccaa7fe370facea6b89bfreed@android.com    if (buffer.readBool()) {
233e0e1da34f3c00ec93c61643d4cf4eea6d27c5fefcommit-bot@chromium.org        fCTable = SkNEW_ARGS(SkColorTable, (buffer));
23449099b25367d1b9ef45ccaa7fe370facea6b89bfreed@android.com    } else {
23549099b25367d1b9ef45ccaa7fe370facea6b89bfreed@android.com        fCTable = NULL;
23649099b25367d1b9ef45ccaa7fe370facea6b89bfreed@android.com    }
237ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com
2387627c657b039ea9aa2a01a7d74e652fe7e27def4reed@google.com    this->setPreLocked(fStorage, fRB, fCTable);
23949099b25367d1b9ef45ccaa7fe370facea6b89bfreed@android.com}
2409ebcac54635cde63110d73ad7c43d70772e7872freed@google.com
2419ebcac54635cde63110d73ad7c43d70772e7872freed@google.com///////////////////////////////////////////////////////////////////////////////
2429ebcac54635cde63110d73ad7c43d70772e7872freed@google.com
2439ebcac54635cde63110d73ad7c43d70772e7872freed@google.comSkPixelRef* SkMallocPixelRef::PRFactory::create(const SkImageInfo& info,
2449ebcac54635cde63110d73ad7c43d70772e7872freed@google.com                                                SkColorTable* ctable) {
2459ebcac54635cde63110d73ad7c43d70772e7872freed@google.com    return SkMallocPixelRef::NewAllocate(info, info.minRowBytes(), ctable);
2469ebcac54635cde63110d73ad7c43d70772e7872freed@google.com}
247