14ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org/*
2685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com * Copyright 2010 The Android Open Source Project
34ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org *
4685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com * Use of this source code is governed by a BSD-style license that can be
5685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com * found in the LICENSE file.
64ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org */
74ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org
84ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org#include "SkPDFImage.h"
94ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org
104ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org#include "SkBitmap.h"
114ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org#include "SkColor.h"
124ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org#include "SkColorPriv.h"
137d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org#include "SkData.h"
147d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org#include "SkFlate.h"
154ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org#include "SkPDFCatalog.h"
16120495f0934cc966632590aa4d00d6dad8d990afvandebo@chromium.org#include "SkRect.h"
174ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org#include "SkStream.h"
184ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org#include "SkString.h"
194ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org#include "SkUnPreMultiply.h"
204ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org
217d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.orgstatic const int kNoColorTransform = 0;
224ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org
237d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.orgstatic bool skip_compression(SkPDFCatalog* catalog) {
247d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    return SkToBool(catalog->getDocumentFlags() &
257d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                    SkPDFDocument::kFavorSpeedOverSize_Flags);
267d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org}
274ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org
287d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.orgstatic size_t get_uncompressed_size(const SkBitmap& bitmap,
297d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                                    const SkIRect& srcRect) {
30bb6a0d330cd7dae11f94aff99c001d4d1eca0716reed@google.com    switch (bitmap.config()) {
317d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        case SkBitmap::kIndex8_Config:
327d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org            return srcRect.width() * srcRect.height();
337d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        case SkBitmap::kARGB_4444_Config:
347d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org            return ((srcRect.width() * 3 + 1) / 2) * srcRect.height();
357d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        case SkBitmap::kRGB_565_Config:
367d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org            return srcRect.width() * 3 * srcRect.height();
377d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        case SkBitmap::kARGB_8888_Config:
387d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org            return srcRect.width() * 3 * srcRect.height();
397d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        case SkBitmap::kA8_Config:
407d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org            return 1;
417d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        default:
427d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org            SkASSERT(false);
437d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org            return 0;
447d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    }
457d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org}
467d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org
477d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.orgstatic SkStream* extract_index8_image(const SkBitmap& bitmap,
487d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                                      const SkIRect& srcRect) {
497d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    const int rowBytes = srcRect.width();
507d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    SkStream* stream = SkNEW_ARGS(SkMemoryStream,
517d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                                  (get_uncompressed_size(bitmap, srcRect)));
527d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    uint8_t* dst = (uint8_t*)stream->getMemoryBase();
537d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org
547d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    for (int y = srcRect.fTop; y < srcRect.fBottom; y++) {
557d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        memcpy(dst, bitmap.getAddr8(srcRect.fLeft, y), rowBytes);
567d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        dst += rowBytes;
577d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    }
587d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    return stream;
597d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org}
607d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org
617d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.orgstatic SkStream* extract_argb4444_data(const SkBitmap& bitmap,
627d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                                       const SkIRect& srcRect,
637d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                                       bool extractAlpha,
647d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                                       bool* isOpaque,
657d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                                       bool* isTransparent) {
667d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    SkStream* stream;
677d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    uint8_t* dst = NULL;
687d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    if (extractAlpha) {
697d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        const int alphaRowBytes = (srcRect.width() + 1) / 2;
707d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        stream = SkNEW_ARGS(SkMemoryStream,
717d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                            (alphaRowBytes * srcRect.height()));
727d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    } else {
737d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        stream = SkNEW_ARGS(SkMemoryStream,
747d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                            (get_uncompressed_size(bitmap, srcRect)));
757d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    }
767d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    dst = (uint8_t*)stream->getMemoryBase();
777d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org
787d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    for (int y = srcRect.fTop; y < srcRect.fBottom; y++) {
797d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        uint16_t* src = bitmap.getAddr16(0, y);
807d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        int x;
817d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        for (x = srcRect.fLeft; x + 1 < srcRect.fRight; x += 2) {
827d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org            if (extractAlpha) {
837d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                dst[0] = (SkGetPackedA4444(src[x]) << 4) |
847d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                    SkGetPackedA4444(src[x + 1]);
857d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                *isOpaque &= dst[0] == SK_AlphaOPAQUE;
867d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                *isTransparent &= dst[0] == SK_AlphaTRANSPARENT;
877d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                dst++;
887d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org            } else {
897d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                dst[0] = (SkGetPackedR4444(src[x]) << 4) |
907d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                    SkGetPackedG4444(src[x]);
917d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                dst[1] = (SkGetPackedB4444(src[x]) << 4) |
927d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                    SkGetPackedR4444(src[x + 1]);
937d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                dst[2] = (SkGetPackedG4444(src[x + 1]) << 4) |
947d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                    SkGetPackedB4444(src[x + 1]);
957d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                dst += 3;
96120495f0934cc966632590aa4d00d6dad8d990afvandebo@chromium.org            }
97120495f0934cc966632590aa4d00d6dad8d990afvandebo@chromium.org        }
987d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        if (srcRect.width() & 1) {
997d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org            if (extractAlpha) {
1007d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                dst[0] = (SkGetPackedA4444(src[x]) << 4);
1017d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                *isOpaque &= dst[0] == (SK_AlphaOPAQUE & 0xF0);
1027d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                *isTransparent &= dst[0] == (SK_AlphaTRANSPARENT & 0xF0);
1037d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                dst++;
1047d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org
1057d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org            } else {
1067d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                dst[0] = (SkGetPackedR4444(src[x]) << 4) |
1077d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                    SkGetPackedG4444(src[x]);
1087d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                dst[1] = (SkGetPackedB4444(src[x]) << 4);
1097d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                dst += 2;
1104ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org            }
1114ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org        }
1127d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    }
1137d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    return stream;
1147d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org}
1157d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org
1167d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.orgstatic SkStream* extract_rgb565_image(const SkBitmap& bitmap,
1177d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                                      const SkIRect& srcRect) {
1187d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    SkStream* stream = SkNEW_ARGS(SkMemoryStream,
1197d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                                  (get_uncompressed_size(bitmap,
1207d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                                                     srcRect)));
1217d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    uint8_t* dst = (uint8_t*)stream->getMemoryBase();
1227d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    for (int y = srcRect.fTop; y < srcRect.fBottom; y++) {
1237d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        uint16_t* src = bitmap.getAddr16(0, y);
1247d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        for (int x = srcRect.fLeft; x < srcRect.fRight; x++) {
1257d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org            dst[0] = SkGetPackedR16(src[x]);
1267d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org            dst[1] = SkGetPackedG16(src[x]);
1277d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org            dst[2] = SkGetPackedB16(src[x]);
1287d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org            dst += 3;
1297d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        }
1307d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    }
1317d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    return stream;
1327d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org}
1337d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org
1347d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.orgstatic SkStream* extract_argb8888_data(const SkBitmap& bitmap,
1357d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                                       const SkIRect& srcRect,
1367d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                                       bool extractAlpha,
1377d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                                       bool* isOpaque,
1387d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                                       bool* isTransparent) {
1397d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    SkStream* stream;
1407d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    if (extractAlpha) {
1417d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        stream = SkNEW_ARGS(SkMemoryStream,
1427d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                            (srcRect.width() * srcRect.height()));
1437d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    } else {
1447d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        stream = SkNEW_ARGS(SkMemoryStream,
1457d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                            (get_uncompressed_size(bitmap, srcRect)));
1467d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    }
1477d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    uint8_t* dst = (uint8_t*)stream->getMemoryBase();
1487d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org
1497d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    for (int y = srcRect.fTop; y < srcRect.fBottom; y++) {
1507d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        uint32_t* src = bitmap.getAddr32(0, y);
1517d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        for (int x = srcRect.fLeft; x < srcRect.fRight; x++) {
1527d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org            if (extractAlpha) {
1537d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                dst[0] = SkGetPackedA32(src[x]);
1547d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                *isOpaque &= dst[0] == SK_AlphaOPAQUE;
1557d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                *isTransparent &= dst[0] == SK_AlphaTRANSPARENT;
1567d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                dst++;
1577d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org            } else {
1587d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                dst[0] = SkGetPackedR32(src[x]);
1597d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                dst[1] = SkGetPackedG32(src[x]);
1607d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                dst[2] = SkGetPackedB32(src[x]);
1617d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                dst += 3;
1624ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org            }
1634ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org        }
1647d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    }
1657d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    return stream;
1667d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org}
1677d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org
1687d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.orgstatic SkStream* extract_a8_alpha(const SkBitmap& bitmap,
1697d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                                  const SkIRect& srcRect,
1707d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                                  bool* isOpaque,
1717d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                                  bool* isTransparent) {
1727d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    const int alphaRowBytes = srcRect.width();
1737d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    SkStream* stream = SkNEW_ARGS(SkMemoryStream,
1747d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                                  (alphaRowBytes * srcRect.height()));
1757d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    uint8_t* alphaDst = (uint8_t*)stream->getMemoryBase();
1767d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org
1777d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    for (int y = srcRect.fTop; y < srcRect.fBottom; y++) {
1787d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        uint8_t* src = bitmap.getAddr8(0, y);
1797d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        for (int x = srcRect.fLeft; x < srcRect.fRight; x++) {
1807d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org            alphaDst[0] = src[x];
1817d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org            *isOpaque &= alphaDst[0] == SK_AlphaOPAQUE;
1827d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org            *isTransparent &= alphaDst[0] == SK_AlphaTRANSPARENT;
1837d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org            alphaDst++;
1847d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        }
1857d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    }
1867d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    return stream;
1877d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org}
1887d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org
1897d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.orgstatic SkStream* create_black_image() {
1907d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    SkStream* stream = SkNEW_ARGS(SkMemoryStream, (1));
1917d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    ((uint8_t*)stream->getMemoryBase())[0] = 0;
1927d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    return stream;
1937d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org}
1947d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org
1957d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org/**
1967d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org * Extract either the color or image data from a SkBitmap into a SkStream.
1977d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org * @param bitmap        Bitmap to extract data from.
1987d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org * @param srcRect       Region in the bitmap to extract.
1997d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org * @param extractAlpha  Set to true to extract the alpha data or false to
2007d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org *                      extract the color data.
2017d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org * @param isTransparent Pointer to a bool to output whether the alpha is
2027d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org *                      completely transparent. May be NULL. Only valid when
2037d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org *                      extractAlpha == true.
2047d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org * @return              Unencoded image data, or NULL if either data was not
2057d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org *                      available or alpha data was requested but the image was
2067d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org *                      entirely transparent or opaque.
2077d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org */
2087d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.orgstatic SkStream* extract_image_data(const SkBitmap& bitmap,
2097d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                                    const SkIRect& srcRect,
2107d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                                    bool extractAlpha, bool* isTransparent) {
2117d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    SkBitmap::Config config = bitmap.config();
2127d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    if (extractAlpha && (config == SkBitmap::kIndex8_Config ||
2137d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org            config == SkBitmap::kRGB_565_Config)) {
2147d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        if (isTransparent != NULL) {
2157d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org            *isTransparent = false;
2167d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        }
2177d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        return NULL;
2187d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    }
2197d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    bool isOpaque = true;
2207d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    bool transparent = extractAlpha;
2217d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    SkStream* stream = NULL;
2227d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org
2237d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    bitmap.lockPixels();
2247d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    switch (config) {
2257d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        case SkBitmap::kIndex8_Config:
2267d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org            if (!extractAlpha) {
2277d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                stream = extract_index8_image(bitmap, srcRect);
2289e4f15cf5552d239f74a73ad139a492119464f56vandebo@chromium.org            }
2299e4f15cf5552d239f74a73ad139a492119464f56vandebo@chromium.org            break;
2307d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        case SkBitmap::kARGB_4444_Config:
2317d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org            stream = extract_argb4444_data(bitmap, srcRect, extractAlpha,
2327d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                                           &isOpaque, &transparent);
2337d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org            break;
2347d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        case SkBitmap::kRGB_565_Config:
2357d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org            if (!extractAlpha) {
2367d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                stream = extract_rgb565_image(bitmap, srcRect);
2377d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org            }
2387d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org            break;
2397d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        case SkBitmap::kARGB_8888_Config:
2407d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org            stream = extract_argb8888_data(bitmap, srcRect, extractAlpha,
2417d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                                           &isOpaque, &transparent);
2427d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org            break;
2437d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        case SkBitmap::kA8_Config:
2447d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org            if (!extractAlpha) {
2457d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                stream = create_black_image();
2467d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org            } else {
2477d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                stream = extract_a8_alpha(bitmap, srcRect,
2487d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                                          &isOpaque, &transparent);
2494ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org            }
2504ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org            break;
2514ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org        default:
2524ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org            SkASSERT(false);
2534ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org    }
25421628c944dfd10e3728375820b2c53adabbd66ffvandebo@chromium.org    bitmap.unlockPixels();
2559e4f15cf5552d239f74a73ad139a492119464f56vandebo@chromium.org
2567d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    if (isTransparent != NULL) {
2577d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        *isTransparent = transparent;
2589e4f15cf5552d239f74a73ad139a492119464f56vandebo@chromium.org    }
2597d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    if (extractAlpha && (transparent || isOpaque)) {
2607d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        SkSafeUnref(stream);
2617d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        return NULL;
2629e4f15cf5552d239f74a73ad139a492119464f56vandebo@chromium.org    }
2637d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    return stream;
2644ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org}
2654ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org
2667d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.orgstatic SkPDFArray* make_indexed_color_space(SkColorTable* table) {
2674ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org    SkPDFArray* result = new SkPDFArray();
2684ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org    result->reserve(4);
269a334eabaf9f6988749fa933dda786aad6eb7a491vandebo@chromium.org    result->appendName("Indexed");
270a334eabaf9f6988749fa933dda786aad6eb7a491vandebo@chromium.org    result->appendName("DeviceRGB");
271a334eabaf9f6988749fa933dda786aad6eb7a491vandebo@chromium.org    result->appendInt(table->count() - 1);
2724ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org
2734ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org    // Potentially, this could be represented in fewer bytes with a stream.
2744ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org    // Max size as a string is 1.5k.
2754ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org    SkString index;
2764ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org    for (int i = 0; i < table->count(); i++) {
2774ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org        char buf[3];
2784ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org        SkColor color = SkUnPreMultiply::PMColorToColor((*table)[i]);
2794ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org        buf[0] = SkGetPackedR32(color);
2804ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org        buf[1] = SkGetPackedG32(color);
2814ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org        buf[2] = SkGetPackedB32(color);
2824ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org        index.append(buf, 3);
2834ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org    }
284a9a5a610cd95fcedb790e5b1a815654c46f92e52vandebo@chromium.org    result->append(new SkPDFString(index))->unref();
2854ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org    return result;
2864ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org}
2874ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org
2880f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org/**
2890f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org * Removes the alpha component of an ARGB color (including unpremultiply) while
2900f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org * keeping the output in the same format as the input.
2910f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org */
2920f18f486966630c3483048de80152b07fa54841cvandebo@chromium.orgstatic uint32_t remove_alpha_argb8888(uint32_t pmColor) {
2930f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org    SkColor color = SkUnPreMultiply::PMColorToColor(pmColor);
2940f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org    return SkPackARGB32NoCheck(SK_AlphaOPAQUE,
2950f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                               SkColorGetR(color),
2960f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                               SkColorGetG(color),
2970f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                               SkColorGetB(color));
2980f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org}
2990f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org
3000f18f486966630c3483048de80152b07fa54841cvandebo@chromium.orgstatic uint16_t remove_alpha_argb4444(uint16_t pmColor) {
3010f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org    return SkPixel32ToPixel4444(
3020f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org            remove_alpha_argb8888(SkPixel4444ToPixel32(pmColor)));
3030f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org}
3040f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org
3050f18f486966630c3483048de80152b07fa54841cvandebo@chromium.orgstatic uint32_t get_argb8888_neighbor_avg_color(const SkBitmap& bitmap,
3060f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                                                int xOrig, int yOrig) {
3070f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org    uint8_t count = 0;
3080f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org    uint16_t r = 0;
3090f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org    uint16_t g = 0;
3100f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org    uint16_t b = 0;
3110f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org
3120f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org    for (int y = yOrig - 1; y <= yOrig + 1; y++) {
3130f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org        if (y < 0 || y >= bitmap.height()) {
3140f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org            continue;
3150f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org        }
3160f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org        uint32_t* src = bitmap.getAddr32(0, y);
3170f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org        for (int x = xOrig - 1; x <= xOrig + 1; x++) {
3180f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org            if (x < 0 || x >= bitmap.width()) {
3190f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                continue;
3200f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org            }
3210f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org            if (SkGetPackedA32(src[x]) != SK_AlphaTRANSPARENT) {
3220f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                uint32_t color = remove_alpha_argb8888(src[x]);
3230f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                r += SkGetPackedR32(color);
3240f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                g += SkGetPackedG32(color);
3250f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                b += SkGetPackedB32(color);
3260f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                count++;
3270f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org            }
3280f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org        }
3290f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org    }
3300f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org
3310f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org    if (count == 0) {
3320f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org        return SkPackARGB32NoCheck(SK_AlphaOPAQUE, 0, 0, 0);
3330f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org    } else {
3340f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org        return SkPackARGB32NoCheck(SK_AlphaOPAQUE,
3350f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                                   r / count, g / count, b / count);
3360f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org    }
3370f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org}
3380f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org
3390f18f486966630c3483048de80152b07fa54841cvandebo@chromium.orgstatic uint16_t get_argb4444_neighbor_avg_color(const SkBitmap& bitmap,
3400f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                                                int xOrig, int yOrig) {
3410f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org    uint8_t count = 0;
3420f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org    uint8_t r = 0;
3430f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org    uint8_t g = 0;
3440f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org    uint8_t b = 0;
3450f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org
3460f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org    for (int y = yOrig - 1; y <= yOrig + 1; y++) {
3470f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org        if (y < 0 || y >= bitmap.height()) {
3480f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org            continue;
3490f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org        }
3500f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org        uint16_t* src = bitmap.getAddr16(0, y);
3510f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org        for (int x = xOrig - 1; x <= xOrig + 1; x++) {
3520f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org            if (x < 0 || x >= bitmap.width()) {
3530f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                continue;
3540f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org            }
3550f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org            if ((SkGetPackedA4444(src[x]) & 0x0F) != SK_AlphaTRANSPARENT) {
3560f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                uint16_t color = remove_alpha_argb4444(src[x]);
3570f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                r += SkGetPackedR4444(color);
3580f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                g += SkGetPackedG4444(color);
3590f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                b += SkGetPackedB4444(color);
3600f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                count++;
3610f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org            }
3620f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org        }
3630f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org    }
3640f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org
3650f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org    if (count == 0) {
3660f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org        return SkPackARGB4444(SK_AlphaOPAQUE & 0x0F, 0, 0, 0);
3670f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org    } else {
3680f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org        return SkPackARGB4444(SK_AlphaOPAQUE & 0x0F,
3690f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                                   r / count, g / count, b / count);
3700f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org    }
3710f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org}
3720f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org
3730f18f486966630c3483048de80152b07fa54841cvandebo@chromium.orgstatic SkBitmap unpremultiply_bitmap(const SkBitmap& bitmap,
3740f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                                     const SkIRect& srcRect) {
3750f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org    SkBitmap outBitmap;
3760f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org    outBitmap.setConfig(bitmap.config(), srcRect.width(), srcRect.height());
3770f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org    outBitmap.allocPixels();
378baef964ce5568a1c483ce71f0587a8847ea51f6brobertphillips@google.com    int dstRow = 0;
3790f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org
3800f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org    outBitmap.lockPixels();
3810f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org    bitmap.lockPixels();
3820f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org    switch (bitmap.config()) {
3830f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org        case SkBitmap::kARGB_4444_Config: {
3840f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org            for (int y = srcRect.fTop; y < srcRect.fBottom; y++) {
3850f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                uint16_t* dst = outBitmap.getAddr16(0, dstRow);
3860f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                uint16_t* src = bitmap.getAddr16(0, y);
3870f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                for (int x = srcRect.fLeft; x < srcRect.fRight; x++) {
3880f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                    uint8_t a = SkGetPackedA4444(src[x]);
3890f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                    // It is necessary to average the color component of
3900f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                    // transparent pixels with their surrounding neighbors
3910f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                    // since the PDF renderer may separately re-sample the
3920f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                    // alpha and color channels when the image is not
3930f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                    // displayed at its native resolution. Since an alpha of
3940f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                    // zero gives no information about the color component,
3950f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                    // the pathological case is a white image with sharp
3960f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                    // transparency bounds - the color channel goes to black,
3970f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                    // and the should-be-transparent pixels are rendered
3980f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                    // as grey because of the separate soft mask and color
3990f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                    // resizing.
4000f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                    if (a == (SK_AlphaTRANSPARENT & 0x0F)) {
4010f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                        *dst = get_argb4444_neighbor_avg_color(bitmap, x, y);
4020f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                    } else {
4030f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                        *dst = remove_alpha_argb4444(src[x]);
4040f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                    }
4050f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                    dst++;
4060f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                }
4070f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                dstRow++;
4080f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org            }
4090f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org            break;
4100f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org        }
4110f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org        case SkBitmap::kARGB_8888_Config: {
4120f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org            for (int y = srcRect.fTop; y < srcRect.fBottom; y++) {
4130f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                uint32_t* dst = outBitmap.getAddr32(0, dstRow);
4140f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                uint32_t* src = bitmap.getAddr32(0, y);
4150f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                for (int x = srcRect.fLeft; x < srcRect.fRight; x++) {
4160f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                    uint8_t a = SkGetPackedA32(src[x]);
4170f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                    if (a == SK_AlphaTRANSPARENT) {
4180f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                        *dst = get_argb8888_neighbor_avg_color(bitmap, x, y);
4190f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                    } else {
4200f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                        *dst = remove_alpha_argb8888(src[x]);
4210f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                    }
4220f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                    dst++;
4230f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                }
4240f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                dstRow++;
4250f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org            }
4260f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org            break;
4270f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org        }
4280f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org        default:
4290f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org            SkASSERT(false);
4300f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org    }
4310f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org    bitmap.unlockPixels();
4320f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org    outBitmap.unlockPixels();
4330f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org
4340f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org    outBitmap.setImmutable();
4350f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org
4360f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org    return outBitmap;
4370f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org}
4380f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org
4399e4f15cf5552d239f74a73ad139a492119464f56vandebo@chromium.org// static
4409e4f15cf5552d239f74a73ad139a492119464f56vandebo@chromium.orgSkPDFImage* SkPDFImage::CreateImage(const SkBitmap& bitmap,
441abf27de148224b3582a0bd8b080dcb95cd946d31edisonn@google.com                                    const SkIRect& srcRect,
442b22c334e8cdb5c71a4c093ba15f75f2b26c4f423commit-bot@chromium.org                                    SkPicture::EncodeBitmap encoder) {
443bb6a0d330cd7dae11f94aff99c001d4d1eca0716reed@google.com    if (bitmap.config() == SkBitmap::kNo_Config) {
4449e4f15cf5552d239f74a73ad139a492119464f56vandebo@chromium.org        return NULL;
445c0db31ffa3b2863d27f630b4809036f8fcc74c7ectguil@chromium.org    }
4469e4f15cf5552d239f74a73ad139a492119464f56vandebo@chromium.org
4477d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    bool isTransparent = false;
4487d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    SkAutoTUnref<SkStream> alphaData;
4497d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    if (!bitmap.isOpaque()) {
4507d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        // Note that isOpaque is not guaranteed to return false for bitmaps
4517d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        // with alpha support but a completely opaque alpha channel,
4527d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        // so alphaData may still be NULL if we have a completely opaque
4537d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        // (or transparent) bitmap.
4547d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        alphaData.reset(
4557d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                extract_image_data(bitmap, srcRect, true, &isTransparent));
4567d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    }
4577d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    if (isTransparent) {
4589e4f15cf5552d239f74a73ad139a492119464f56vandebo@chromium.org        return NULL;
4599e4f15cf5552d239f74a73ad139a492119464f56vandebo@chromium.org    }
4609e4f15cf5552d239f74a73ad139a492119464f56vandebo@chromium.org
4610f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org    SkPDFImage* image;
4620f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org    SkBitmap::Config config = bitmap.config();
4630f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org    if (alphaData.get() != NULL && (config == SkBitmap::kARGB_8888_Config ||
4640f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org            config == SkBitmap::kARGB_4444_Config)) {
4650f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org        SkBitmap unpremulBitmap = unpremultiply_bitmap(bitmap, srcRect);
4660f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org        image = SkNEW_ARGS(SkPDFImage, (NULL, unpremulBitmap, false,
4670f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                           SkIRect::MakeWH(srcRect.width(), srcRect.height()),
4680f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org                           encoder));
4690f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org    } else {
4700f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org        image = SkNEW_ARGS(SkPDFImage, (NULL, bitmap, false, srcRect, encoder));
4710f18f486966630c3483048de80152b07fa54841cvandebo@chromium.org    }
4727d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    if (alphaData.get() != NULL) {
4737d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        SkAutoTUnref<SkPDFImage> mask(
4747d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                SkNEW_ARGS(SkPDFImage, (alphaData.get(), bitmap,
4757d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                                        true, srcRect, NULL)));
4767d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        image->addSMask(mask);
4779e4f15cf5552d239f74a73ad139a492119464f56vandebo@chromium.org    }
4787d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org
4799e4f15cf5552d239f74a73ad139a492119464f56vandebo@chromium.org    return image;
4809e4f15cf5552d239f74a73ad139a492119464f56vandebo@chromium.org}
4819e4f15cf5552d239f74a73ad139a492119464f56vandebo@chromium.org
4829e4f15cf5552d239f74a73ad139a492119464f56vandebo@chromium.orgSkPDFImage::~SkPDFImage() {
4839e4f15cf5552d239f74a73ad139a492119464f56vandebo@chromium.org    fResources.unrefAll();
4849e4f15cf5552d239f74a73ad139a492119464f56vandebo@chromium.org}
4859e4f15cf5552d239f74a73ad139a492119464f56vandebo@chromium.org
486a9a5a610cd95fcedb790e5b1a815654c46f92e52vandebo@chromium.orgSkPDFImage* SkPDFImage::addSMask(SkPDFImage* mask) {
4879e4f15cf5552d239f74a73ad139a492119464f56vandebo@chromium.org    fResources.push(mask);
4889e4f15cf5552d239f74a73ad139a492119464f56vandebo@chromium.org    mask->ref();
489a9a5a610cd95fcedb790e5b1a815654c46f92e52vandebo@chromium.org    insert("SMask", new SkPDFObjRef(mask))->unref();
490a9a5a610cd95fcedb790e5b1a815654c46f92e52vandebo@chromium.org    return mask;
4919e4f15cf5552d239f74a73ad139a492119464f56vandebo@chromium.org}
4929e4f15cf5552d239f74a73ad139a492119464f56vandebo@chromium.org
49309b4813b6bd356d371952c4346f1f9fbe02fdfceedisonn@google.comvoid SkPDFImage::getResources(const SkTSet<SkPDFObject*>& knownResourceObjects,
49409b4813b6bd356d371952c4346f1f9fbe02fdfceedisonn@google.com                              SkTSet<SkPDFObject*>* newResourceObjects) {
49509b4813b6bd356d371952c4346f1f9fbe02fdfceedisonn@google.com    GetResourcesHelper(&fResources, knownResourceObjects, newResourceObjects);
4969e4f15cf5552d239f74a73ad139a492119464f56vandebo@chromium.org}
4979e4f15cf5552d239f74a73ad139a492119464f56vandebo@chromium.org
4987d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.orgSkPDFImage::SkPDFImage(SkStream* stream,
499abf27de148224b3582a0bd8b080dcb95cd946d31edisonn@google.com                       const SkBitmap& bitmap,
5007d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                       bool isAlpha,
501abf27de148224b3582a0bd8b080dcb95cd946d31edisonn@google.com                       const SkIRect& srcRect,
502b22c334e8cdb5c71a4c093ba15f75f2b26c4f423commit-bot@chromium.org                       SkPicture::EncodeBitmap encoder)
50363f299a82355c9ce032f6825d3cd214d6dca9e51commit-bot@chromium.org    : fIsAlpha(isAlpha),
5047d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org      fSrcRect(srcRect),
5057d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org      fEncoder(encoder) {
5067d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org
50763f299a82355c9ce032f6825d3cd214d6dca9e51commit-bot@chromium.org    if (bitmap.isImmutable()) {
50863f299a82355c9ce032f6825d3cd214d6dca9e51commit-bot@chromium.org        fBitmap = bitmap;
50963f299a82355c9ce032f6825d3cd214d6dca9e51commit-bot@chromium.org    } else {
51063f299a82355c9ce032f6825d3cd214d6dca9e51commit-bot@chromium.org        bitmap.deepCopyTo(&fBitmap, bitmap.config());
51163f299a82355c9ce032f6825d3cd214d6dca9e51commit-bot@chromium.org        fBitmap.setImmutable();
51263f299a82355c9ce032f6825d3cd214d6dca9e51commit-bot@chromium.org    }
51363f299a82355c9ce032f6825d3cd214d6dca9e51commit-bot@chromium.org
5147d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    if (stream != NULL) {
5157d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        setData(stream);
5167d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        fStreamValid = true;
5177d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    } else {
5187d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        fStreamValid = false;
5197d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    }
5207d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org
521bb6a0d330cd7dae11f94aff99c001d4d1eca0716reed@google.com    SkBitmap::Config config = fBitmap.config();
5229e4f15cf5552d239f74a73ad139a492119464f56vandebo@chromium.org
523a334eabaf9f6988749fa933dda786aad6eb7a491vandebo@chromium.org    insertName("Type", "XObject");
524a334eabaf9f6988749fa933dda786aad6eb7a491vandebo@chromium.org    insertName("Subtype", "Image");
525a9a5a610cd95fcedb790e5b1a815654c46f92e52vandebo@chromium.org
5268793ad7e7045baaeed4c9bd6dde482961b527c47rmistry@google.com    bool alphaOnly = (config == SkBitmap::kA8_Config);
5277d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org
5287d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    if (!isAlpha && alphaOnly) {
5299e4f15cf5552d239f74a73ad139a492119464f56vandebo@chromium.org        // For alpha only images, we stretch a single pixel of black for
5309e4f15cf5552d239f74a73ad139a492119464f56vandebo@chromium.org        // the color/shape part.
5315b20098a0c3b7d3fe65d8e636bc898fb661f6fa8vandebo@chromium.org        SkAutoTUnref<SkPDFInt> one(new SkPDFInt(1));
532a9a5a610cd95fcedb790e5b1a815654c46f92e52vandebo@chromium.org        insert("Width", one.get());
533a9a5a610cd95fcedb790e5b1a815654c46f92e52vandebo@chromium.org        insert("Height", one.get());
5349e4f15cf5552d239f74a73ad139a492119464f56vandebo@chromium.org    } else {
5357d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        insertInt("Width", fSrcRect.width());
5367d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        insertInt("Height", fSrcRect.height());
5379e4f15cf5552d239f74a73ad139a492119464f56vandebo@chromium.org    }
5384ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org
5397d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    if (isAlpha || alphaOnly) {
540a334eabaf9f6988749fa933dda786aad6eb7a491vandebo@chromium.org        insertName("ColorSpace", "DeviceGray");
5417046fabd572d913a9a02106de3b053cfeed7062freed@google.com    } else if (config == SkBitmap::kIndex8_Config) {
5427d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        SkAutoLockPixels alp(fBitmap);
543a9a5a610cd95fcedb790e5b1a815654c46f92e52vandebo@chromium.org        insert("ColorSpace",
5447d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org               make_indexed_color_space(fBitmap.getColorTable()))->unref();
5454ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org    } else {
546a334eabaf9f6988749fa933dda786aad6eb7a491vandebo@chromium.org        insertName("ColorSpace", "DeviceRGB");
5474ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org    }
5484ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org
5499e4f15cf5552d239f74a73ad139a492119464f56vandebo@chromium.org    int bitsPerComp = 8;
550c0db31ffa3b2863d27f630b4809036f8fcc74c7ectguil@chromium.org    if (config == SkBitmap::kARGB_4444_Config) {
5519e4f15cf5552d239f74a73ad139a492119464f56vandebo@chromium.org        bitsPerComp = 4;
552c0db31ffa3b2863d27f630b4809036f8fcc74c7ectguil@chromium.org    }
553a334eabaf9f6988749fa933dda786aad6eb7a491vandebo@chromium.org    insertInt("BitsPerComponent", bitsPerComp);
5544ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org
5554ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org    if (config == SkBitmap::kRGB_565_Config) {
5567d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        SkASSERT(!isAlpha);
5575b20098a0c3b7d3fe65d8e636bc898fb661f6fa8vandebo@chromium.org        SkAutoTUnref<SkPDFInt> zeroVal(new SkPDFInt(0));
5585b20098a0c3b7d3fe65d8e636bc898fb661f6fa8vandebo@chromium.org        SkAutoTUnref<SkPDFScalar> scale5Val(
559dfc928cc9afc242d1125e8d5ae48e8bca66c4834commit-bot@chromium.org                new SkPDFScalar(8.2258f));  // 255/2^5-1
5605b20098a0c3b7d3fe65d8e636bc898fb661f6fa8vandebo@chromium.org        SkAutoTUnref<SkPDFScalar> scale6Val(
561dfc928cc9afc242d1125e8d5ae48e8bca66c4834commit-bot@chromium.org                new SkPDFScalar(4.0476f));  // 255/2^6-1
5625b20098a0c3b7d3fe65d8e636bc898fb661f6fa8vandebo@chromium.org        SkAutoTUnref<SkPDFArray> decodeValue(new SkPDFArray());
5634ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org        decodeValue->reserve(6);
5644ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org        decodeValue->append(zeroVal.get());
5654ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org        decodeValue->append(scale5Val.get());
5664ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org        decodeValue->append(zeroVal.get());
5674ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org        decodeValue->append(scale6Val.get());
5684ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org        decodeValue->append(zeroVal.get());
5694ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org        decodeValue->append(scale5Val.get());
5704ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org        insert("Decode", decodeValue.get());
5714ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org    }
5724ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org}
5737d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org
5747d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.orgSkPDFImage::SkPDFImage(SkPDFImage& pdfImage)
5757d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    : SkPDFStream(pdfImage),
5767d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org      fBitmap(pdfImage.fBitmap),
5777d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org      fIsAlpha(pdfImage.fIsAlpha),
5787d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org      fSrcRect(pdfImage.fSrcRect),
5797d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org      fEncoder(pdfImage.fEncoder),
5807d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org      fStreamValid(pdfImage.fStreamValid) {
5817d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    // Nothing to do here - the image params are already copied in SkPDFStream's
5827d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    // constructor, and the bitmap will be regenerated and encoded in
5837d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    // populate.
5847d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org}
5857d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org
5867d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.orgbool SkPDFImage::populate(SkPDFCatalog* catalog) {
5877d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    if (getState() == kUnused_State) {
5887d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        // Initializing image data for the first time.
5897d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        SkDynamicMemoryWStream dctCompressedWStream;
5907d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        if (!skip_compression(catalog) && fEncoder &&
591b22c334e8cdb5c71a4c093ba15f75f2b26c4f423commit-bot@chromium.org                get_uncompressed_size(fBitmap, fSrcRect) > 1) {
592b22c334e8cdb5c71a4c093ba15f75f2b26c4f423commit-bot@chromium.org            SkBitmap subset;
593b22c334e8cdb5c71a4c093ba15f75f2b26c4f423commit-bot@chromium.org            // Extract subset
594b22c334e8cdb5c71a4c093ba15f75f2b26c4f423commit-bot@chromium.org            if (!fBitmap.extractSubset(&subset, fSrcRect)) {
595b22c334e8cdb5c71a4c093ba15f75f2b26c4f423commit-bot@chromium.org                // TODO(edisonn) It fails only for kA1_Config, if that is a
596b22c334e8cdb5c71a4c093ba15f75f2b26c4f423commit-bot@chromium.org                // major concern we will fix it later, so far it is NYI.
597b22c334e8cdb5c71a4c093ba15f75f2b26c4f423commit-bot@chromium.org                return false;
598b22c334e8cdb5c71a4c093ba15f75f2b26c4f423commit-bot@chromium.org            }
599b22c334e8cdb5c71a4c093ba15f75f2b26c4f423commit-bot@chromium.org            size_t pixelRefOffset = 0;
600b22c334e8cdb5c71a4c093ba15f75f2b26c4f423commit-bot@chromium.org            SkAutoTUnref<SkData> data(fEncoder(&pixelRefOffset, subset));
601b22c334e8cdb5c71a4c093ba15f75f2b26c4f423commit-bot@chromium.org            if (data.get() && data->size() < get_uncompressed_size(fBitmap,
602b22c334e8cdb5c71a4c093ba15f75f2b26c4f423commit-bot@chromium.org                                                                   fSrcRect)) {
603b22c334e8cdb5c71a4c093ba15f75f2b26c4f423commit-bot@chromium.org                SkAutoTUnref<SkStream> stream(SkNEW_ARGS(SkMemoryStream,
604b22c334e8cdb5c71a4c093ba15f75f2b26c4f423commit-bot@chromium.org                                                         (data)));
605b22c334e8cdb5c71a4c093ba15f75f2b26c4f423commit-bot@chromium.org                setData(stream.get());
606b22c334e8cdb5c71a4c093ba15f75f2b26c4f423commit-bot@chromium.org
607b22c334e8cdb5c71a4c093ba15f75f2b26c4f423commit-bot@chromium.org                insertName("Filter", "DCTDecode");
608b22c334e8cdb5c71a4c093ba15f75f2b26c4f423commit-bot@chromium.org                insertInt("ColorTransform", kNoColorTransform);
609b22c334e8cdb5c71a4c093ba15f75f2b26c4f423commit-bot@chromium.org                insertInt("Length", getData()->getLength());
610b22c334e8cdb5c71a4c093ba15f75f2b26c4f423commit-bot@chromium.org                setState(kCompressed_State);
611b22c334e8cdb5c71a4c093ba15f75f2b26c4f423commit-bot@chromium.org                return true;
612b22c334e8cdb5c71a4c093ba15f75f2b26c4f423commit-bot@chromium.org            }
6137d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        }
6147d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        // Fallback method
6157d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        if (!fStreamValid) {
6167d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org            SkAutoTUnref<SkStream> stream(
6177d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org                    extract_image_data(fBitmap, fSrcRect, fIsAlpha, NULL));
6187d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org            setData(stream);
6197d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org            fStreamValid = true;
6207d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        }
6217d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        return INHERITED::populate(catalog);
6227d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    } else if (getState() == kNoCompression_State &&
6237d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org            !skip_compression(catalog) &&
6247d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org            (SkFlate::HaveFlate() || fEncoder)) {
6257d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        // Compression has not been requested when the stream was first created,
6267d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        // but the new catalog wants it compressed.
6277d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        if (!getSubstitute()) {
6287d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org            SkPDFStream* substitute = SkNEW_ARGS(SkPDFImage, (*this));
6297d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org            setSubstitute(substitute);
6307d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org            catalog->setSubstitute(this, substitute);
6317d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        }
6327d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org        return false;
6337d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    }
6347d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org    return true;
6357d2fd33f9fecd8d71341716c6f0032ce515cdba6commit-bot@chromium.org}
636