19b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org/*
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2010 The Android Open Source Project
39b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org *
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.
69b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org */
79b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org
89b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org#include "SkPDFImage.h"
99b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org
109b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org#include "SkBitmap.h"
119b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org#include "SkColor.h"
129b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org#include "SkColorPriv.h"
13181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org#include "SkData.h"
14181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org#include "SkFlate.h"
159b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org#include "SkPDFCatalog.h"
16befebb8a8437ce69e3a416b417cb27b66273128dvandebo@chromium.org#include "SkRect.h"
179b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org#include "SkStream.h"
189b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org#include "SkString.h"
199b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org#include "SkUnPreMultiply.h"
209b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org
21181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.orgstatic const int kNoColorTransform = 0;
229b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org
23181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.orgstatic bool skip_compression(SkPDFCatalog* catalog) {
24181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    return SkToBool(catalog->getDocumentFlags() &
25181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                    SkPDFDocument::kFavorSpeedOverSize_Flags);
26181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org}
279b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org
28181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.orgstatic size_t get_uncompressed_size(const SkBitmap& bitmap,
29181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                                    const SkIRect& srcRect) {
30c77392ed58ec78ab19fa0e3ff99fb8110854fba2reed    switch (bitmap.colorType()) {
31c77392ed58ec78ab19fa0e3ff99fb8110854fba2reed        case kIndex_8_SkColorType:
32181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org            return srcRect.width() * srcRect.height();
33c77392ed58ec78ab19fa0e3ff99fb8110854fba2reed        case kARGB_4444_SkColorType:
34181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org            return ((srcRect.width() * 3 + 1) / 2) * srcRect.height();
35c77392ed58ec78ab19fa0e3ff99fb8110854fba2reed        case kRGB_565_SkColorType:
36181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org            return srcRect.width() * 3 * srcRect.height();
37c77392ed58ec78ab19fa0e3ff99fb8110854fba2reed        case kRGBA_8888_SkColorType:
38c77392ed58ec78ab19fa0e3ff99fb8110854fba2reed        case kBGRA_8888_SkColorType:
39181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org            return srcRect.width() * 3 * srcRect.height();
40c77392ed58ec78ab19fa0e3ff99fb8110854fba2reed        case kAlpha_8_SkColorType:
41181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org            return 1;
42181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org        default:
43181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org            SkASSERT(false);
44181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org            return 0;
45181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    }
46181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org}
47181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org
48181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.orgstatic SkStream* extract_index8_image(const SkBitmap& bitmap,
49181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                                      const SkIRect& srcRect) {
50181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    const int rowBytes = srcRect.width();
51181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    SkStream* stream = SkNEW_ARGS(SkMemoryStream,
52181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                                  (get_uncompressed_size(bitmap, srcRect)));
53181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    uint8_t* dst = (uint8_t*)stream->getMemoryBase();
54181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org
55181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    for (int y = srcRect.fTop; y < srcRect.fBottom; y++) {
56181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org        memcpy(dst, bitmap.getAddr8(srcRect.fLeft, y), rowBytes);
57181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org        dst += rowBytes;
58181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    }
59181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    return stream;
60181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org}
61181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org
62181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.orgstatic SkStream* extract_argb4444_data(const SkBitmap& bitmap,
63181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                                       const SkIRect& srcRect,
64181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                                       bool extractAlpha,
65181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                                       bool* isOpaque,
66181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                                       bool* isTransparent) {
67181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    SkStream* stream;
68181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    uint8_t* dst = NULL;
69181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    if (extractAlpha) {
70181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org        const int alphaRowBytes = (srcRect.width() + 1) / 2;
71181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org        stream = SkNEW_ARGS(SkMemoryStream,
72181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                            (alphaRowBytes * srcRect.height()));
73181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    } else {
74181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org        stream = SkNEW_ARGS(SkMemoryStream,
75181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                            (get_uncompressed_size(bitmap, srcRect)));
76181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    }
77181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    dst = (uint8_t*)stream->getMemoryBase();
78181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org
79181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    for (int y = srcRect.fTop; y < srcRect.fBottom; y++) {
80181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org        uint16_t* src = bitmap.getAddr16(0, y);
81181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org        int x;
82181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org        for (x = srcRect.fLeft; x + 1 < srcRect.fRight; x += 2) {
83181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org            if (extractAlpha) {
84181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                dst[0] = (SkGetPackedA4444(src[x]) << 4) |
85181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                    SkGetPackedA4444(src[x + 1]);
86181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                *isOpaque &= dst[0] == SK_AlphaOPAQUE;
87181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                *isTransparent &= dst[0] == SK_AlphaTRANSPARENT;
88181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                dst++;
89181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org            } else {
90181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                dst[0] = (SkGetPackedR4444(src[x]) << 4) |
91181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                    SkGetPackedG4444(src[x]);
92181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                dst[1] = (SkGetPackedB4444(src[x]) << 4) |
93181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                    SkGetPackedR4444(src[x + 1]);
94181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                dst[2] = (SkGetPackedG4444(src[x + 1]) << 4) |
95181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                    SkGetPackedB4444(src[x + 1]);
96181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                dst += 3;
97befebb8a8437ce69e3a416b417cb27b66273128dvandebo@chromium.org            }
98befebb8a8437ce69e3a416b417cb27b66273128dvandebo@chromium.org        }
99181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org        if (srcRect.width() & 1) {
100181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org            if (extractAlpha) {
101181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                dst[0] = (SkGetPackedA4444(src[x]) << 4);
102181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                *isOpaque &= dst[0] == (SK_AlphaOPAQUE & 0xF0);
103181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                *isTransparent &= dst[0] == (SK_AlphaTRANSPARENT & 0xF0);
104181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                dst++;
105181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org
106181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org            } else {
107181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                dst[0] = (SkGetPackedR4444(src[x]) << 4) |
108181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                    SkGetPackedG4444(src[x]);
109181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                dst[1] = (SkGetPackedB4444(src[x]) << 4);
110181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                dst += 2;
1119b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org            }
1129b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org        }
113181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    }
114181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    return stream;
115181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org}
116181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org
117181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.orgstatic SkStream* extract_rgb565_image(const SkBitmap& bitmap,
118181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                                      const SkIRect& srcRect) {
119181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    SkStream* stream = SkNEW_ARGS(SkMemoryStream,
120181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                                  (get_uncompressed_size(bitmap,
121181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                                                     srcRect)));
122181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    uint8_t* dst = (uint8_t*)stream->getMemoryBase();
123181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    for (int y = srcRect.fTop; y < srcRect.fBottom; y++) {
124181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org        uint16_t* src = bitmap.getAddr16(0, y);
125181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org        for (int x = srcRect.fLeft; x < srcRect.fRight; x++) {
126181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org            dst[0] = SkGetPackedR16(src[x]);
127181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org            dst[1] = SkGetPackedG16(src[x]);
128181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org            dst[2] = SkGetPackedB16(src[x]);
129181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org            dst += 3;
130181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org        }
131181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    }
132181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    return stream;
133181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org}
134181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org
135181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.orgstatic SkStream* extract_argb8888_data(const SkBitmap& bitmap,
136181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                                       const SkIRect& srcRect,
137181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                                       bool extractAlpha,
138181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                                       bool* isOpaque,
139181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                                       bool* isTransparent) {
140181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    SkStream* stream;
141181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    if (extractAlpha) {
142181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org        stream = SkNEW_ARGS(SkMemoryStream,
143181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                            (srcRect.width() * srcRect.height()));
144181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    } else {
145181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org        stream = SkNEW_ARGS(SkMemoryStream,
146181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                            (get_uncompressed_size(bitmap, srcRect)));
147181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    }
148181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    uint8_t* dst = (uint8_t*)stream->getMemoryBase();
149181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org
150181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    for (int y = srcRect.fTop; y < srcRect.fBottom; y++) {
151181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org        uint32_t* src = bitmap.getAddr32(0, y);
152181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org        for (int x = srcRect.fLeft; x < srcRect.fRight; x++) {
153181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org            if (extractAlpha) {
154181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                dst[0] = SkGetPackedA32(src[x]);
155181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                *isOpaque &= dst[0] == SK_AlphaOPAQUE;
156181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                *isTransparent &= dst[0] == SK_AlphaTRANSPARENT;
157181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                dst++;
158181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org            } else {
159181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                dst[0] = SkGetPackedR32(src[x]);
160181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                dst[1] = SkGetPackedG32(src[x]);
161181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                dst[2] = SkGetPackedB32(src[x]);
162181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                dst += 3;
1639b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org            }
1649b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org        }
165181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    }
166181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    return stream;
167181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org}
168181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org
169181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.orgstatic SkStream* extract_a8_alpha(const SkBitmap& bitmap,
170181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                                  const SkIRect& srcRect,
171181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                                  bool* isOpaque,
172181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                                  bool* isTransparent) {
173181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    const int alphaRowBytes = srcRect.width();
174181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    SkStream* stream = SkNEW_ARGS(SkMemoryStream,
175181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                                  (alphaRowBytes * srcRect.height()));
176181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    uint8_t* alphaDst = (uint8_t*)stream->getMemoryBase();
177181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org
178181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    for (int y = srcRect.fTop; y < srcRect.fBottom; y++) {
179181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org        uint8_t* src = bitmap.getAddr8(0, y);
180181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org        for (int x = srcRect.fLeft; x < srcRect.fRight; x++) {
181181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org            alphaDst[0] = src[x];
182181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org            *isOpaque &= alphaDst[0] == SK_AlphaOPAQUE;
183181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org            *isTransparent &= alphaDst[0] == SK_AlphaTRANSPARENT;
184181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org            alphaDst++;
185181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org        }
186181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    }
187181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    return stream;
188181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org}
189181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org
190181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.orgstatic SkStream* create_black_image() {
191181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    SkStream* stream = SkNEW_ARGS(SkMemoryStream, (1));
192181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    ((uint8_t*)stream->getMemoryBase())[0] = 0;
193181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    return stream;
194181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org}
195181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org
196181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org/**
197181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org * Extract either the color or image data from a SkBitmap into a SkStream.
198181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org * @param bitmap        Bitmap to extract data from.
199181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org * @param srcRect       Region in the bitmap to extract.
200181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org * @param extractAlpha  Set to true to extract the alpha data or false to
201181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org *                      extract the color data.
202181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org * @param isTransparent Pointer to a bool to output whether the alpha is
203181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org *                      completely transparent. May be NULL. Only valid when
204181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org *                      extractAlpha == true.
205181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org * @return              Unencoded image data, or NULL if either data was not
206181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org *                      available or alpha data was requested but the image was
207181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org *                      entirely transparent or opaque.
208181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org */
209181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.orgstatic SkStream* extract_image_data(const SkBitmap& bitmap,
210181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                                    const SkIRect& srcRect,
211181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                                    bool extractAlpha, bool* isTransparent) {
212c77392ed58ec78ab19fa0e3ff99fb8110854fba2reed    SkColorType colorType = bitmap.colorType();
213c77392ed58ec78ab19fa0e3ff99fb8110854fba2reed    if (extractAlpha && (kIndex_8_SkColorType == colorType ||
214c77392ed58ec78ab19fa0e3ff99fb8110854fba2reed                         kRGB_565_SkColorType == colorType)) {
215181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org        if (isTransparent != NULL) {
216181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org            *isTransparent = false;
217181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org        }
218181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org        return NULL;
219181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    }
220181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    bool isOpaque = true;
221181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    bool transparent = extractAlpha;
222181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    SkStream* stream = NULL;
223181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org
224181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    bitmap.lockPixels();
225c77392ed58ec78ab19fa0e3ff99fb8110854fba2reed    switch (colorType) {
226c77392ed58ec78ab19fa0e3ff99fb8110854fba2reed        case kIndex_8_SkColorType:
227181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org            if (!extractAlpha) {
228181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                stream = extract_index8_image(bitmap, srcRect);
2291cfa2c458626abe952a63b1a9397d8e496a134d6vandebo@chromium.org            }
2301cfa2c458626abe952a63b1a9397d8e496a134d6vandebo@chromium.org            break;
231c77392ed58ec78ab19fa0e3ff99fb8110854fba2reed        case kARGB_4444_SkColorType:
232181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org            stream = extract_argb4444_data(bitmap, srcRect, extractAlpha,
233181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                                           &isOpaque, &transparent);
234181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org            break;
235c77392ed58ec78ab19fa0e3ff99fb8110854fba2reed        case kRGB_565_SkColorType:
236181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org            if (!extractAlpha) {
237181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                stream = extract_rgb565_image(bitmap, srcRect);
238181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org            }
239181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org            break;
240c77392ed58ec78ab19fa0e3ff99fb8110854fba2reed        case kN32_SkColorType:
241181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org            stream = extract_argb8888_data(bitmap, srcRect, extractAlpha,
242181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                                           &isOpaque, &transparent);
243181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org            break;
244c77392ed58ec78ab19fa0e3ff99fb8110854fba2reed        case kAlpha_8_SkColorType:
245181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org            if (!extractAlpha) {
246181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                stream = create_black_image();
247181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org            } else {
248181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                stream = extract_a8_alpha(bitmap, srcRect,
249181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                                          &isOpaque, &transparent);
2509b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org            }
2519b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org            break;
2529b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org        default:
2539b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org            SkASSERT(false);
2549b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    }
255ad11495e3d0809e4cc264f7302e399a7a5f430d0vandebo@chromium.org    bitmap.unlockPixels();
2561cfa2c458626abe952a63b1a9397d8e496a134d6vandebo@chromium.org
257181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    if (isTransparent != NULL) {
258181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org        *isTransparent = transparent;
2591cfa2c458626abe952a63b1a9397d8e496a134d6vandebo@chromium.org    }
260181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    if (extractAlpha && (transparent || isOpaque)) {
261181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org        SkSafeUnref(stream);
262181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org        return NULL;
2631cfa2c458626abe952a63b1a9397d8e496a134d6vandebo@chromium.org    }
264181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    return stream;
2659b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org}
2669b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org
267181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.orgstatic SkPDFArray* make_indexed_color_space(SkColorTable* table) {
2689b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    SkPDFArray* result = new SkPDFArray();
2699b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    result->reserve(4);
27006f7f4051eeb299cb15b308edabd17344c183a36vandebo@chromium.org    result->appendName("Indexed");
27106f7f4051eeb299cb15b308edabd17344c183a36vandebo@chromium.org    result->appendName("DeviceRGB");
27206f7f4051eeb299cb15b308edabd17344c183a36vandebo@chromium.org    result->appendInt(table->count() - 1);
2739b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org
2749b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    // Potentially, this could be represented in fewer bytes with a stream.
2759b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    // Max size as a string is 1.5k.
2769b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    SkString index;
2779b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    for (int i = 0; i < table->count(); i++) {
2789b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org        char buf[3];
2799b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org        SkColor color = SkUnPreMultiply::PMColorToColor((*table)[i]);
2809b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org        buf[0] = SkGetPackedR32(color);
2819b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org        buf[1] = SkGetPackedG32(color);
2829b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org        buf[2] = SkGetPackedB32(color);
2839b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org        index.append(buf, 3);
2849b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    }
285f7c157610ff85f7323f5e213b62478dcc66edbecvandebo@chromium.org    result->append(new SkPDFString(index))->unref();
2869b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    return result;
2879b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org}
2889b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org
289ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org/**
290ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org * Removes the alpha component of an ARGB color (including unpremultiply) while
291ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org * keeping the output in the same format as the input.
292ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org */
293ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.orgstatic uint32_t remove_alpha_argb8888(uint32_t pmColor) {
294ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org    SkColor color = SkUnPreMultiply::PMColorToColor(pmColor);
295ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org    return SkPackARGB32NoCheck(SK_AlphaOPAQUE,
296ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                               SkColorGetR(color),
297ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                               SkColorGetG(color),
298ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                               SkColorGetB(color));
299ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org}
300ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org
301ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.orgstatic uint16_t remove_alpha_argb4444(uint16_t pmColor) {
302ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org    return SkPixel32ToPixel4444(
303ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org            remove_alpha_argb8888(SkPixel4444ToPixel32(pmColor)));
304ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org}
305ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org
306ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.orgstatic uint32_t get_argb8888_neighbor_avg_color(const SkBitmap& bitmap,
307ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                                                int xOrig, int yOrig) {
308ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org    uint8_t count = 0;
309ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org    uint16_t r = 0;
310ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org    uint16_t g = 0;
311ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org    uint16_t b = 0;
312ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org
313ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org    for (int y = yOrig - 1; y <= yOrig + 1; y++) {
314ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org        if (y < 0 || y >= bitmap.height()) {
315ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org            continue;
316ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org        }
317ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org        uint32_t* src = bitmap.getAddr32(0, y);
318ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org        for (int x = xOrig - 1; x <= xOrig + 1; x++) {
319ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org            if (x < 0 || x >= bitmap.width()) {
320ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                continue;
321ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org            }
322ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org            if (SkGetPackedA32(src[x]) != SK_AlphaTRANSPARENT) {
323ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                uint32_t color = remove_alpha_argb8888(src[x]);
324ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                r += SkGetPackedR32(color);
325ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                g += SkGetPackedG32(color);
326ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                b += SkGetPackedB32(color);
327ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                count++;
328ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org            }
329ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org        }
330ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org    }
331ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org
332ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org    if (count == 0) {
333ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org        return SkPackARGB32NoCheck(SK_AlphaOPAQUE, 0, 0, 0);
334ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org    } else {
335ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org        return SkPackARGB32NoCheck(SK_AlphaOPAQUE,
336ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                                   r / count, g / count, b / count);
337ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org    }
338ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org}
339ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org
340ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.orgstatic uint16_t get_argb4444_neighbor_avg_color(const SkBitmap& bitmap,
341ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                                                int xOrig, int yOrig) {
342ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org    uint8_t count = 0;
343ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org    uint8_t r = 0;
344ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org    uint8_t g = 0;
345ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org    uint8_t b = 0;
346ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org
347ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org    for (int y = yOrig - 1; y <= yOrig + 1; y++) {
348ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org        if (y < 0 || y >= bitmap.height()) {
349ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org            continue;
350ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org        }
351ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org        uint16_t* src = bitmap.getAddr16(0, y);
352ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org        for (int x = xOrig - 1; x <= xOrig + 1; x++) {
353ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org            if (x < 0 || x >= bitmap.width()) {
354ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                continue;
355ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org            }
356ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org            if ((SkGetPackedA4444(src[x]) & 0x0F) != SK_AlphaTRANSPARENT) {
357ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                uint16_t color = remove_alpha_argb4444(src[x]);
358ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                r += SkGetPackedR4444(color);
359ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                g += SkGetPackedG4444(color);
360ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                b += SkGetPackedB4444(color);
361ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                count++;
362ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org            }
363ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org        }
364ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org    }
365ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org
366ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org    if (count == 0) {
367ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org        return SkPackARGB4444(SK_AlphaOPAQUE & 0x0F, 0, 0, 0);
368ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org    } else {
369ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org        return SkPackARGB4444(SK_AlphaOPAQUE & 0x0F,
370ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                                   r / count, g / count, b / count);
371ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org    }
372ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org}
373ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org
374ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.orgstatic SkBitmap unpremultiply_bitmap(const SkBitmap& bitmap,
375ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                                     const SkIRect& srcRect) {
376ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org    SkBitmap outBitmap;
377c77392ed58ec78ab19fa0e3ff99fb8110854fba2reed    outBitmap.allocPixels(bitmap.info().makeWH(srcRect.width(), srcRect.height()));
378a4662865e37a2ca95b5e3379072f6a274acc8ac8robertphillips@google.com    int dstRow = 0;
379ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org
380ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org    outBitmap.lockPixels();
381ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org    bitmap.lockPixels();
382c77392ed58ec78ab19fa0e3ff99fb8110854fba2reed    switch (bitmap.colorType()) {
383c77392ed58ec78ab19fa0e3ff99fb8110854fba2reed        case kARGB_4444_SkColorType: {
384ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org            for (int y = srcRect.fTop; y < srcRect.fBottom; y++) {
385ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                uint16_t* dst = outBitmap.getAddr16(0, dstRow);
386ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                uint16_t* src = bitmap.getAddr16(0, y);
387ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                for (int x = srcRect.fLeft; x < srcRect.fRight; x++) {
388ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                    uint8_t a = SkGetPackedA4444(src[x]);
389ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                    // It is necessary to average the color component of
390ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                    // transparent pixels with their surrounding neighbors
391ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                    // since the PDF renderer may separately re-sample the
392ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                    // alpha and color channels when the image is not
393ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                    // displayed at its native resolution. Since an alpha of
394ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                    // zero gives no information about the color component,
395ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                    // the pathological case is a white image with sharp
396ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                    // transparency bounds - the color channel goes to black,
397ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                    // and the should-be-transparent pixels are rendered
398ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                    // as grey because of the separate soft mask and color
399ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                    // resizing.
400ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                    if (a == (SK_AlphaTRANSPARENT & 0x0F)) {
401ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                        *dst = get_argb4444_neighbor_avg_color(bitmap, x, y);
402ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                    } else {
403ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                        *dst = remove_alpha_argb4444(src[x]);
404ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                    }
405ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                    dst++;
406ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                }
407ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                dstRow++;
408ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org            }
409ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org            break;
410ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org        }
411c77392ed58ec78ab19fa0e3ff99fb8110854fba2reed        case kN32_SkColorType: {
412ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org            for (int y = srcRect.fTop; y < srcRect.fBottom; y++) {
413ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                uint32_t* dst = outBitmap.getAddr32(0, dstRow);
414ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                uint32_t* src = bitmap.getAddr32(0, y);
415ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                for (int x = srcRect.fLeft; x < srcRect.fRight; x++) {
416ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                    uint8_t a = SkGetPackedA32(src[x]);
417ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                    if (a == SK_AlphaTRANSPARENT) {
418ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                        *dst = get_argb8888_neighbor_avg_color(bitmap, x, y);
419ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                    } else {
420ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                        *dst = remove_alpha_argb8888(src[x]);
421ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                    }
422ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                    dst++;
423ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                }
424ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                dstRow++;
425ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org            }
426ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org            break;
427ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org        }
428ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org        default:
429ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org            SkASSERT(false);
430ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org    }
431ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org    bitmap.unlockPixels();
432ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org    outBitmap.unlockPixels();
433ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org
434ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org    outBitmap.setImmutable();
435ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org
436ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org    return outBitmap;
437ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org}
438ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org
4391cfa2c458626abe952a63b1a9397d8e496a134d6vandebo@chromium.org// static
4401cfa2c458626abe952a63b1a9397d8e496a134d6vandebo@chromium.orgSkPDFImage* SkPDFImage::CreateImage(const SkBitmap& bitmap,
441d9dfa18372119c8e1318125d2075fa80e0819094edisonn@google.com                                    const SkIRect& srcRect,
442608ea6508ae2e9ea05ea863ba50fc27d44d2eae9commit-bot@chromium.org                                    SkPicture::EncodeBitmap encoder) {
443c77392ed58ec78ab19fa0e3ff99fb8110854fba2reed    if (bitmap.colorType() == kUnknown_SkColorType) {
4441cfa2c458626abe952a63b1a9397d8e496a134d6vandebo@chromium.org        return NULL;
445769fa6a013baca6d7404e2bf096a34a7e3635fa5ctguil@chromium.org    }
4461cfa2c458626abe952a63b1a9397d8e496a134d6vandebo@chromium.org
447181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    bool isTransparent = false;
448181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    SkAutoTUnref<SkStream> alphaData;
449181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    if (!bitmap.isOpaque()) {
450181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org        // Note that isOpaque is not guaranteed to return false for bitmaps
451181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org        // with alpha support but a completely opaque alpha channel,
452181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org        // so alphaData may still be NULL if we have a completely opaque
453181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org        // (or transparent) bitmap.
454181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org        alphaData.reset(
455181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                extract_image_data(bitmap, srcRect, true, &isTransparent));
456181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    }
457181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    if (isTransparent) {
4581cfa2c458626abe952a63b1a9397d8e496a134d6vandebo@chromium.org        return NULL;
4591cfa2c458626abe952a63b1a9397d8e496a134d6vandebo@chromium.org    }
4601cfa2c458626abe952a63b1a9397d8e496a134d6vandebo@chromium.org
461ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org    SkPDFImage* image;
462c77392ed58ec78ab19fa0e3ff99fb8110854fba2reed    SkColorType colorType = bitmap.colorType();
463c77392ed58ec78ab19fa0e3ff99fb8110854fba2reed    if (alphaData.get() != NULL && (kN32_SkColorType == colorType ||
464c77392ed58ec78ab19fa0e3ff99fb8110854fba2reed                                    kARGB_4444_SkColorType == colorType)) {
465ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org        SkBitmap unpremulBitmap = unpremultiply_bitmap(bitmap, srcRect);
466ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org        image = SkNEW_ARGS(SkPDFImage, (NULL, unpremulBitmap, false,
467ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                           SkIRect::MakeWH(srcRect.width(), srcRect.height()),
468ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org                           encoder));
469ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org    } else {
470ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org        image = SkNEW_ARGS(SkPDFImage, (NULL, bitmap, false, srcRect, encoder));
471ece95c32d529d7b54ca14a936782acaefe9869a1vandebo@chromium.org    }
472181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    if (alphaData.get() != NULL) {
473181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org        SkAutoTUnref<SkPDFImage> mask(
474181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                SkNEW_ARGS(SkPDFImage, (alphaData.get(), bitmap,
475181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                                        true, srcRect, NULL)));
476181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org        image->addSMask(mask);
4771cfa2c458626abe952a63b1a9397d8e496a134d6vandebo@chromium.org    }
478181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org
4791cfa2c458626abe952a63b1a9397d8e496a134d6vandebo@chromium.org    return image;
4801cfa2c458626abe952a63b1a9397d8e496a134d6vandebo@chromium.org}
4811cfa2c458626abe952a63b1a9397d8e496a134d6vandebo@chromium.org
4821cfa2c458626abe952a63b1a9397d8e496a134d6vandebo@chromium.orgSkPDFImage::~SkPDFImage() {
4831cfa2c458626abe952a63b1a9397d8e496a134d6vandebo@chromium.org    fResources.unrefAll();
4841cfa2c458626abe952a63b1a9397d8e496a134d6vandebo@chromium.org}
4851cfa2c458626abe952a63b1a9397d8e496a134d6vandebo@chromium.org
486f7c157610ff85f7323f5e213b62478dcc66edbecvandebo@chromium.orgSkPDFImage* SkPDFImage::addSMask(SkPDFImage* mask) {
4871cfa2c458626abe952a63b1a9397d8e496a134d6vandebo@chromium.org    fResources.push(mask);
4881cfa2c458626abe952a63b1a9397d8e496a134d6vandebo@chromium.org    mask->ref();
489f7c157610ff85f7323f5e213b62478dcc66edbecvandebo@chromium.org    insert("SMask", new SkPDFObjRef(mask))->unref();
490f7c157610ff85f7323f5e213b62478dcc66edbecvandebo@chromium.org    return mask;
4911cfa2c458626abe952a63b1a9397d8e496a134d6vandebo@chromium.org}
4921cfa2c458626abe952a63b1a9397d8e496a134d6vandebo@chromium.org
4936addb1930013ebb2f984045141650fd7afcfa90fedisonn@google.comvoid SkPDFImage::getResources(const SkTSet<SkPDFObject*>& knownResourceObjects,
4946addb1930013ebb2f984045141650fd7afcfa90fedisonn@google.com                              SkTSet<SkPDFObject*>* newResourceObjects) {
4956addb1930013ebb2f984045141650fd7afcfa90fedisonn@google.com    GetResourcesHelper(&fResources, knownResourceObjects, newResourceObjects);
4961cfa2c458626abe952a63b1a9397d8e496a134d6vandebo@chromium.org}
4971cfa2c458626abe952a63b1a9397d8e496a134d6vandebo@chromium.org
498181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.orgSkPDFImage::SkPDFImage(SkStream* stream,
499d9dfa18372119c8e1318125d2075fa80e0819094edisonn@google.com                       const SkBitmap& bitmap,
500181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                       bool isAlpha,
501d9dfa18372119c8e1318125d2075fa80e0819094edisonn@google.com                       const SkIRect& srcRect,
502608ea6508ae2e9ea05ea863ba50fc27d44d2eae9commit-bot@chromium.org                       SkPicture::EncodeBitmap encoder)
50306822ea87266548b2dfa5d3421e4d874e1290980commit-bot@chromium.org    : fIsAlpha(isAlpha),
504181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org      fSrcRect(srcRect),
505181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org      fEncoder(encoder) {
506181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org
50706822ea87266548b2dfa5d3421e4d874e1290980commit-bot@chromium.org    if (bitmap.isImmutable()) {
50806822ea87266548b2dfa5d3421e4d874e1290980commit-bot@chromium.org        fBitmap = bitmap;
50906822ea87266548b2dfa5d3421e4d874e1290980commit-bot@chromium.org    } else {
5106285f4f7662853336b788d6ee3e177c396f7fb01commit-bot@chromium.org        bitmap.deepCopyTo(&fBitmap);
51106822ea87266548b2dfa5d3421e4d874e1290980commit-bot@chromium.org        fBitmap.setImmutable();
51206822ea87266548b2dfa5d3421e4d874e1290980commit-bot@chromium.org    }
51306822ea87266548b2dfa5d3421e4d874e1290980commit-bot@chromium.org
514181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    if (stream != NULL) {
515181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org        setData(stream);
516181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org        fStreamValid = true;
517181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    } else {
518181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org        fStreamValid = false;
519181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    }
520181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org
521c77392ed58ec78ab19fa0e3ff99fb8110854fba2reed    SkColorType colorType = fBitmap.colorType();
5221cfa2c458626abe952a63b1a9397d8e496a134d6vandebo@chromium.org
52306f7f4051eeb299cb15b308edabd17344c183a36vandebo@chromium.org    insertName("Type", "XObject");
52406f7f4051eeb299cb15b308edabd17344c183a36vandebo@chromium.org    insertName("Subtype", "Image");
525f7c157610ff85f7323f5e213b62478dcc66edbecvandebo@chromium.org
526c77392ed58ec78ab19fa0e3ff99fb8110854fba2reed    bool alphaOnly = (kAlpha_8_SkColorType == colorType);
527181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org
528181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    if (!isAlpha && alphaOnly) {
5291cfa2c458626abe952a63b1a9397d8e496a134d6vandebo@chromium.org        // For alpha only images, we stretch a single pixel of black for
5301cfa2c458626abe952a63b1a9397d8e496a134d6vandebo@chromium.org        // the color/shape part.
531d96d17b9c113ac694138224249ff2ce643e961ddvandebo@chromium.org        SkAutoTUnref<SkPDFInt> one(new SkPDFInt(1));
532f7c157610ff85f7323f5e213b62478dcc66edbecvandebo@chromium.org        insert("Width", one.get());
533f7c157610ff85f7323f5e213b62478dcc66edbecvandebo@chromium.org        insert("Height", one.get());
5341cfa2c458626abe952a63b1a9397d8e496a134d6vandebo@chromium.org    } else {
535181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org        insertInt("Width", fSrcRect.width());
536181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org        insertInt("Height", fSrcRect.height());
5371cfa2c458626abe952a63b1a9397d8e496a134d6vandebo@chromium.org    }
5389b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org
539181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    if (isAlpha || alphaOnly) {
54006f7f4051eeb299cb15b308edabd17344c183a36vandebo@chromium.org        insertName("ColorSpace", "DeviceGray");
541c77392ed58ec78ab19fa0e3ff99fb8110854fba2reed    } else if (kIndex_8_SkColorType == colorType) {
542181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org        SkAutoLockPixels alp(fBitmap);
543f7c157610ff85f7323f5e213b62478dcc66edbecvandebo@chromium.org        insert("ColorSpace",
544181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org               make_indexed_color_space(fBitmap.getColorTable()))->unref();
5459b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    } else {
54606f7f4051eeb299cb15b308edabd17344c183a36vandebo@chromium.org        insertName("ColorSpace", "DeviceRGB");
5479b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    }
5489b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org
5491cfa2c458626abe952a63b1a9397d8e496a134d6vandebo@chromium.org    int bitsPerComp = 8;
550c77392ed58ec78ab19fa0e3ff99fb8110854fba2reed    if (kARGB_4444_SkColorType == colorType) {
5511cfa2c458626abe952a63b1a9397d8e496a134d6vandebo@chromium.org        bitsPerComp = 4;
552769fa6a013baca6d7404e2bf096a34a7e3635fa5ctguil@chromium.org    }
55306f7f4051eeb299cb15b308edabd17344c183a36vandebo@chromium.org    insertInt("BitsPerComponent", bitsPerComp);
5549b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org
555c77392ed58ec78ab19fa0e3ff99fb8110854fba2reed    if (kRGB_565_SkColorType == colorType) {
556181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org        SkASSERT(!isAlpha);
557d96d17b9c113ac694138224249ff2ce643e961ddvandebo@chromium.org        SkAutoTUnref<SkPDFInt> zeroVal(new SkPDFInt(0));
558d96d17b9c113ac694138224249ff2ce643e961ddvandebo@chromium.org        SkAutoTUnref<SkPDFScalar> scale5Val(
5594b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org                new SkPDFScalar(8.2258f));  // 255/2^5-1
560d96d17b9c113ac694138224249ff2ce643e961ddvandebo@chromium.org        SkAutoTUnref<SkPDFScalar> scale6Val(
5614b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org                new SkPDFScalar(4.0476f));  // 255/2^6-1
562d96d17b9c113ac694138224249ff2ce643e961ddvandebo@chromium.org        SkAutoTUnref<SkPDFArray> decodeValue(new SkPDFArray());
5639b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org        decodeValue->reserve(6);
5649b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org        decodeValue->append(zeroVal.get());
5659b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org        decodeValue->append(scale5Val.get());
5669b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org        decodeValue->append(zeroVal.get());
5679b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org        decodeValue->append(scale6Val.get());
5689b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org        decodeValue->append(zeroVal.get());
5699b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org        decodeValue->append(scale5Val.get());
5709b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org        insert("Decode", decodeValue.get());
5719b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org    }
5729b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org}
573181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org
574181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.orgSkPDFImage::SkPDFImage(SkPDFImage& pdfImage)
575181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    : SkPDFStream(pdfImage),
576181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org      fBitmap(pdfImage.fBitmap),
577181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org      fIsAlpha(pdfImage.fIsAlpha),
578181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org      fSrcRect(pdfImage.fSrcRect),
579181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org      fEncoder(pdfImage.fEncoder),
580181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org      fStreamValid(pdfImage.fStreamValid) {
581181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    // Nothing to do here - the image params are already copied in SkPDFStream's
582181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    // constructor, and the bitmap will be regenerated and encoded in
583181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    // populate.
584181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org}
585181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org
586181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.orgbool SkPDFImage::populate(SkPDFCatalog* catalog) {
587181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    if (getState() == kUnused_State) {
588181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org        // Initializing image data for the first time.
589181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org        SkDynamicMemoryWStream dctCompressedWStream;
590181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org        if (!skip_compression(catalog) && fEncoder &&
591608ea6508ae2e9ea05ea863ba50fc27d44d2eae9commit-bot@chromium.org                get_uncompressed_size(fBitmap, fSrcRect) > 1) {
592608ea6508ae2e9ea05ea863ba50fc27d44d2eae9commit-bot@chromium.org            SkBitmap subset;
593608ea6508ae2e9ea05ea863ba50fc27d44d2eae9commit-bot@chromium.org            // Extract subset
594608ea6508ae2e9ea05ea863ba50fc27d44d2eae9commit-bot@chromium.org            if (!fBitmap.extractSubset(&subset, fSrcRect)) {
595608ea6508ae2e9ea05ea863ba50fc27d44d2eae9commit-bot@chromium.org                return false;
596608ea6508ae2e9ea05ea863ba50fc27d44d2eae9commit-bot@chromium.org            }
597608ea6508ae2e9ea05ea863ba50fc27d44d2eae9commit-bot@chromium.org            size_t pixelRefOffset = 0;
598608ea6508ae2e9ea05ea863ba50fc27d44d2eae9commit-bot@chromium.org            SkAutoTUnref<SkData> data(fEncoder(&pixelRefOffset, subset));
599608ea6508ae2e9ea05ea863ba50fc27d44d2eae9commit-bot@chromium.org            if (data.get() && data->size() < get_uncompressed_size(fBitmap,
600608ea6508ae2e9ea05ea863ba50fc27d44d2eae9commit-bot@chromium.org                                                                   fSrcRect)) {
601608ea6508ae2e9ea05ea863ba50fc27d44d2eae9commit-bot@chromium.org                SkAutoTUnref<SkStream> stream(SkNEW_ARGS(SkMemoryStream,
602608ea6508ae2e9ea05ea863ba50fc27d44d2eae9commit-bot@chromium.org                                                         (data)));
603608ea6508ae2e9ea05ea863ba50fc27d44d2eae9commit-bot@chromium.org                setData(stream.get());
604608ea6508ae2e9ea05ea863ba50fc27d44d2eae9commit-bot@chromium.org
605608ea6508ae2e9ea05ea863ba50fc27d44d2eae9commit-bot@chromium.org                insertName("Filter", "DCTDecode");
606608ea6508ae2e9ea05ea863ba50fc27d44d2eae9commit-bot@chromium.org                insertInt("ColorTransform", kNoColorTransform);
607608ea6508ae2e9ea05ea863ba50fc27d44d2eae9commit-bot@chromium.org                insertInt("Length", getData()->getLength());
608608ea6508ae2e9ea05ea863ba50fc27d44d2eae9commit-bot@chromium.org                setState(kCompressed_State);
609608ea6508ae2e9ea05ea863ba50fc27d44d2eae9commit-bot@chromium.org                return true;
610608ea6508ae2e9ea05ea863ba50fc27d44d2eae9commit-bot@chromium.org            }
611181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org        }
612181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org        // Fallback method
613181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org        if (!fStreamValid) {
614181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org            SkAutoTUnref<SkStream> stream(
615181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org                    extract_image_data(fBitmap, fSrcRect, fIsAlpha, NULL));
616181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org            setData(stream);
617181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org            fStreamValid = true;
618181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org        }
619181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org        return INHERITED::populate(catalog);
620181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    } else if (getState() == kNoCompression_State &&
621181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org            !skip_compression(catalog) &&
622181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org            (SkFlate::HaveFlate() || fEncoder)) {
623181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org        // Compression has not been requested when the stream was first created,
624181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org        // but the new catalog wants it compressed.
625181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org        if (!getSubstitute()) {
626181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org            SkPDFStream* substitute = SkNEW_ARGS(SkPDFImage, (*this));
627181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org            setSubstitute(substitute);
628181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org            catalog->setSubstitute(this, substitute);
629181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org        }
630181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org        return false;
631181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    }
632181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org    return true;
633181fcb4a21cb87292eded6675a1df05cf9c3aacccommit-bot@chromium.org}
634