SkPDFBitmap.cpp revision 3f4671871fac8e5439440ce756d0666bc2a96f46
11b5c604d9d344537941b11b136348edfc39f236chalcanary/*
21b5c604d9d344537941b11b136348edfc39f236chalcanary * Copyright 2015 Google Inc.
31b5c604d9d344537941b11b136348edfc39f236chalcanary *
41b5c604d9d344537941b11b136348edfc39f236chalcanary * Use of this source code is governed by a BSD-style license that can be
51b5c604d9d344537941b11b136348edfc39f236chalcanary * found in the LICENSE file.
61b5c604d9d344537941b11b136348edfc39f236chalcanary */
71b5c604d9d344537941b11b136348edfc39f236chalcanary
84f29c20f20ce62150998786be8b9f8a81a901d72Hal Canary#include "SkPDFBitmap.h"
94f29c20f20ce62150998786be8b9f8a81a901d72Hal Canary
101b5c604d9d344537941b11b136348edfc39f236chalcanary#include "SkColorPriv.h"
11a8448bc3dfe0f2e768838b4416fb3ebf823b694ehalcanary#include "SkData.h"
12d9e57158ebd9b1f8317f0d76ef0402cfce0b0253halcanary#include "SkDeflate.h"
134f29c20f20ce62150998786be8b9f8a81a901d72Hal Canary#include "SkImage.h"
1496287f7af7ff6aaa48b8d28ec6b7b79836da2d7chalcanary#include "SkJpegInfo.h"
151b5c604d9d344537941b11b136348edfc39f236chalcanary#include "SkPDFCanon.h"
16b8d6af169bf631dcb68ba5a796436434ff78be65martina.kollarova#include "SkPDFTypes.h"
174f29c20f20ce62150998786be8b9f8a81a901d72Hal Canary#include "SkPDFUtils.h"
181b5c604d9d344537941b11b136348edfc39f236chalcanary#include "SkStream.h"
191b5c604d9d344537941b11b136348edfc39f236chalcanary#include "SkUnPreMultiply.h"
201b5c604d9d344537941b11b136348edfc39f236chalcanary
217a14b310d6c618fa2151d93a43b29f9599adc32ahalcanarybool image_compute_is_opaque(const SkImage* image) {
227a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary    if (image->isOpaque()) {
237a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary        return true;
247a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary    }
257a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary    // keep output PDF small at cost of possible resource use.
267a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary    SkBitmap bm;
274f29c20f20ce62150998786be8b9f8a81a901d72Hal Canary    // if image can not be read, treat as transparent.
284f29c20f20ce62150998786be8b9f8a81a901d72Hal Canary    return SkPDFUtils::ToBitmap(image, &bm) && SkBitmap::ComputeIsOpaque(bm);
297a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary}
307a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary
311b5c604d9d344537941b11b136348edfc39f236chalcanary////////////////////////////////////////////////////////////////////////////////
321b5c604d9d344537941b11b136348edfc39f236chalcanary
331b5c604d9d344537941b11b136348edfc39f236chalcanarystatic void pdf_stream_begin(SkWStream* stream) {
341b5c604d9d344537941b11b136348edfc39f236chalcanary    static const char streamBegin[] = " stream\n";
351b5c604d9d344537941b11b136348edfc39f236chalcanary    stream->write(streamBegin, strlen(streamBegin));
361b5c604d9d344537941b11b136348edfc39f236chalcanary}
371b5c604d9d344537941b11b136348edfc39f236chalcanary
381b5c604d9d344537941b11b136348edfc39f236chalcanarystatic void pdf_stream_end(SkWStream* stream) {
391b5c604d9d344537941b11b136348edfc39f236chalcanary    static const char streamEnd[] = "\nendstream";
401b5c604d9d344537941b11b136348edfc39f236chalcanary    stream->write(streamEnd, strlen(streamEnd));
411b5c604d9d344537941b11b136348edfc39f236chalcanary}
421b5c604d9d344537941b11b136348edfc39f236chalcanary
43db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary////////////////////////////////////////////////////////////////////////////////
441b5c604d9d344537941b11b136348edfc39f236chalcanary
451b5c604d9d344537941b11b136348edfc39f236chalcanary// write a single byte to a stream n times.
461b5c604d9d344537941b11b136348edfc39f236chalcanarystatic void fill_stream(SkWStream* out, char value, size_t n) {
471b5c604d9d344537941b11b136348edfc39f236chalcanary    char buffer[4096];
481b5c604d9d344537941b11b136348edfc39f236chalcanary    memset(buffer, value, sizeof(buffer));
49db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary    for (size_t i = 0; i < n / sizeof(buffer); ++i) {
50db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary        out->write(buffer, sizeof(buffer));
511b5c604d9d344537941b11b136348edfc39f236chalcanary    }
52db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary    out->write(buffer, n % sizeof(buffer));
531b5c604d9d344537941b11b136348edfc39f236chalcanary}
541b5c604d9d344537941b11b136348edfc39f236chalcanary
55aa4ba90792a99eed96ac51006bd478d453a751c4halcanary// TODO(reed@): Decide if these five functions belong in SkColorPriv.h
56aa4ba90792a99eed96ac51006bd478d453a751c4halcanarystatic bool SkIsBGRA(SkColorType ct) {
57aa4ba90792a99eed96ac51006bd478d453a751c4halcanary    SkASSERT(kBGRA_8888_SkColorType == ct || kRGBA_8888_SkColorType == ct);
58aa4ba90792a99eed96ac51006bd478d453a751c4halcanary    return kBGRA_8888_SkColorType == ct;
59aa4ba90792a99eed96ac51006bd478d453a751c4halcanary}
60aa4ba90792a99eed96ac51006bd478d453a751c4halcanary
61aa4ba90792a99eed96ac51006bd478d453a751c4halcanary// Interpret value as the given 4-byte SkColorType (BGRA_8888 or
62aa4ba90792a99eed96ac51006bd478d453a751c4halcanary// RGBA_8888) and return the appropriate component.  Each component
63aa4ba90792a99eed96ac51006bd478d453a751c4halcanary// should be interpreted according to the associated SkAlphaType and
64aa4ba90792a99eed96ac51006bd478d453a751c4halcanary// SkColorProfileType.
65aa4ba90792a99eed96ac51006bd478d453a751c4halcanarystatic U8CPU SkGetA32Component(uint32_t value, SkColorType ct) {
66aa4ba90792a99eed96ac51006bd478d453a751c4halcanary    return (value >> (SkIsBGRA(ct) ? SK_BGRA_A32_SHIFT : SK_RGBA_A32_SHIFT)) & 0xFF;
67aa4ba90792a99eed96ac51006bd478d453a751c4halcanary}
68aa4ba90792a99eed96ac51006bd478d453a751c4halcanarystatic U8CPU SkGetR32Component(uint32_t value, SkColorType ct) {
69aa4ba90792a99eed96ac51006bd478d453a751c4halcanary    return (value >> (SkIsBGRA(ct) ? SK_BGRA_R32_SHIFT : SK_RGBA_R32_SHIFT)) & 0xFF;
70aa4ba90792a99eed96ac51006bd478d453a751c4halcanary}
71aa4ba90792a99eed96ac51006bd478d453a751c4halcanarystatic U8CPU SkGetG32Component(uint32_t value, SkColorType ct) {
72aa4ba90792a99eed96ac51006bd478d453a751c4halcanary    return (value >> (SkIsBGRA(ct) ? SK_BGRA_G32_SHIFT : SK_RGBA_G32_SHIFT)) & 0xFF;
73aa4ba90792a99eed96ac51006bd478d453a751c4halcanary}
74aa4ba90792a99eed96ac51006bd478d453a751c4halcanarystatic U8CPU SkGetB32Component(uint32_t value, SkColorType ct) {
75aa4ba90792a99eed96ac51006bd478d453a751c4halcanary    return (value >> (SkIsBGRA(ct) ? SK_BGRA_B32_SHIFT : SK_RGBA_B32_SHIFT)) & 0xFF;
76aa4ba90792a99eed96ac51006bd478d453a751c4halcanary}
77aa4ba90792a99eed96ac51006bd478d453a751c4halcanary
78db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary// unpremultiply and extract R, G, B components.
79aa4ba90792a99eed96ac51006bd478d453a751c4halcanarystatic void pmcolor_to_rgb24(uint32_t color, uint8_t* rgb, SkColorType ct) {
805b474d36238e38642add8d4b54cb9ac80935262bHal Canary    SkPMColorAssert(color);
81aa4ba90792a99eed96ac51006bd478d453a751c4halcanary    uint32_t s = SkUnPreMultiply::GetScale(SkGetA32Component(color, ct));
82aa4ba90792a99eed96ac51006bd478d453a751c4halcanary    rgb[0] = SkUnPreMultiply::ApplyScale(s, SkGetR32Component(color, ct));
83aa4ba90792a99eed96ac51006bd478d453a751c4halcanary    rgb[1] = SkUnPreMultiply::ApplyScale(s, SkGetG32Component(color, ct));
84aa4ba90792a99eed96ac51006bd478d453a751c4halcanary    rgb[2] = SkUnPreMultiply::ApplyScale(s, SkGetB32Component(color, ct));
85db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary}
86db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary
87db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary/* It is necessary to average the color component of transparent
88db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary   pixels with their surrounding neighbors since the PDF renderer may
89db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary   separately re-sample the alpha and color channels when the image is
90db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary   not displayed at its native resolution. Since an alpha of zero
91db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary   gives no information about the color component, the pathological
92db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary   case is a white image with sharp transparency bounds - the color
93db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary   channel goes to black, and the should-be-transparent pixels are
94db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary   rendered as grey because of the separate soft mask and color
95db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary   resizing. e.g.: gm/bitmappremul.cpp */
96db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanarystatic void get_neighbor_avg_color(const SkBitmap& bm,
97db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary                                   int xOrig,
98db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary                                   int yOrig,
99aa4ba90792a99eed96ac51006bd478d453a751c4halcanary                                   uint8_t rgb[3],
100aa4ba90792a99eed96ac51006bd478d453a751c4halcanary                                   SkColorType ct) {
101db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary    unsigned a = 0, r = 0, g = 0, b = 0;
102db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary    // Clamp the range to the edge of the bitmap.
103db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary    int ymin = SkTMax(0, yOrig - 1);
104db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary    int ymax = SkTMin(yOrig + 1, bm.height() - 1);
105db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary    int xmin = SkTMax(0, xOrig - 1);
106db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary    int xmax = SkTMin(xOrig + 1, bm.width() - 1);
107db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary    for (int y = ymin; y <= ymax; ++y) {
108aa4ba90792a99eed96ac51006bd478d453a751c4halcanary        uint32_t* scanline = bm.getAddr32(0, y);
109db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary        for (int x = xmin; x <= xmax; ++x) {
110aa4ba90792a99eed96ac51006bd478d453a751c4halcanary            uint32_t color = scanline[x];
1115b474d36238e38642add8d4b54cb9ac80935262bHal Canary            SkPMColorAssert(color);
112aa4ba90792a99eed96ac51006bd478d453a751c4halcanary            a += SkGetA32Component(color, ct);
113aa4ba90792a99eed96ac51006bd478d453a751c4halcanary            r += SkGetR32Component(color, ct);
114aa4ba90792a99eed96ac51006bd478d453a751c4halcanary            g += SkGetG32Component(color, ct);
115aa4ba90792a99eed96ac51006bd478d453a751c4halcanary            b += SkGetB32Component(color, ct);
1161b5c604d9d344537941b11b136348edfc39f236chalcanary        }
1171b5c604d9d344537941b11b136348edfc39f236chalcanary    }
118db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary    if (a > 0) {
119db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary        rgb[0] = SkToU8(255 * r / a);
120db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary        rgb[1] = SkToU8(255 * g / a);
121db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary        rgb[2] = SkToU8(255 * b / a);
1221b5c604d9d344537941b11b136348edfc39f236chalcanary    } else {
123db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary        rgb[0] = rgb[1] = rgb[2] = 0;
12486ad8d643624a55b02e529100bbe4e2940115fa1halcanary    }
12586ad8d643624a55b02e529100bbe4e2940115fa1halcanary}
12686ad8d643624a55b02e529100bbe4e2940115fa1halcanary
127db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanarystatic size_t pixel_count(const SkBitmap& bm) {
128db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary    return SkToSizeT(bm.width()) * SkToSizeT(bm.height());
129db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary}
130db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary
1313f4671871fac8e5439440ce756d0666bc2a96f46Hal Canarystatic const SkBitmap& supported_colortype(const SkBitmap& input, SkBitmap* copy) {
1323f4671871fac8e5439440ce756d0666bc2a96f46Hal Canary    switch (input.colorType()) {
1333f4671871fac8e5439440ce756d0666bc2a96f46Hal Canary        case kUnknown_SkColorType:
1343f4671871fac8e5439440ce756d0666bc2a96f46Hal Canary            SkDEBUGFAIL("kUnknown_SkColorType");
1353f4671871fac8e5439440ce756d0666bc2a96f46Hal Canary        case kAlpha_8_SkColorType:
1363f4671871fac8e5439440ce756d0666bc2a96f46Hal Canary        case kRGB_565_SkColorType:
1373f4671871fac8e5439440ce756d0666bc2a96f46Hal Canary        case kRGBA_8888_SkColorType:
1383f4671871fac8e5439440ce756d0666bc2a96f46Hal Canary        case kBGRA_8888_SkColorType:
1393f4671871fac8e5439440ce756d0666bc2a96f46Hal Canary        case kGray_8_SkColorType:
1403f4671871fac8e5439440ce756d0666bc2a96f46Hal Canary            return input;  // supported
1413f4671871fac8e5439440ce756d0666bc2a96f46Hal Canary        default:
1423f4671871fac8e5439440ce756d0666bc2a96f46Hal Canary            // if other colortypes are introduced in the future,
1433f4671871fac8e5439440ce756d0666bc2a96f46Hal Canary            // they will hit this code.
1443f4671871fac8e5439440ce756d0666bc2a96f46Hal Canary            break;
145db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary    }
1463f4671871fac8e5439440ce756d0666bc2a96f46Hal Canary    // Fallback for rarely used ARGB_4444 and ARGB_F16: do a wasteful tmp copy.
14768b8e3d50d0954eb5eeb7f625f06026c7fbd38c1Matt Sarett    copy->allocPixels(input.info().makeColorType(kN32_SkColorType));
14868b8e3d50d0954eb5eeb7f625f06026c7fbd38c1Matt Sarett    SkAssertResult(input.readPixels(copy->info(), copy->getPixels(), copy->rowBytes(), 0, 0));
149db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary    copy->setImmutable();
150db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary    return *copy;
151db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary}
152db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary
153db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanarystatic size_t pdf_color_component_count(SkColorType ct) {
154db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary    switch (ct) {
1553f4671871fac8e5439440ce756d0666bc2a96f46Hal Canary        case kUnknown_SkColorType:
1563f4671871fac8e5439440ce756d0666bc2a96f46Hal Canary            SkDEBUGFAIL("kUnknown_SkColorType");
1573f4671871fac8e5439440ce756d0666bc2a96f46Hal Canary        case kAlpha_8_SkColorType:
1583f4671871fac8e5439440ce756d0666bc2a96f46Hal Canary        case kGray_8_SkColorType:
1593f4671871fac8e5439440ce756d0666bc2a96f46Hal Canary            return 1;
160db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary        case kRGB_565_SkColorType:
161aa4ba90792a99eed96ac51006bd478d453a751c4halcanary        case kRGBA_8888_SkColorType:
162aa4ba90792a99eed96ac51006bd478d453a751c4halcanary        case kBGRA_8888_SkColorType:
1633f4671871fac8e5439440ce756d0666bc2a96f46Hal Canary        default:  // converted to N32
164db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary            return 3;
165db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary    }
166db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary}
167db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary
168db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanarystatic void bitmap_to_pdf_pixels(const SkBitmap& bitmap, SkWStream* out) {
169db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary    if (!bitmap.getPixels()) {
170db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary        size_t size = pixel_count(bitmap) *
171db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary                      pdf_color_component_count(bitmap.colorType());
172db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary        fill_stream(out, '\x00', size);
1731b5c604d9d344537941b11b136348edfc39f236chalcanary        return;
1741b5c604d9d344537941b11b136348edfc39f236chalcanary    }
175db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary    SkBitmap copy;
1763f4671871fac8e5439440ce756d0666bc2a96f46Hal Canary    const SkBitmap& bm = supported_colortype(bitmap, &copy);
177aa4ba90792a99eed96ac51006bd478d453a751c4halcanary    SkColorType colorType = bm.colorType();
1787b9eabb392902e6e8f4206ba8aa041524258fd0fhalcanary    SkAlphaType alphaType = bm.alphaType();
179aa4ba90792a99eed96ac51006bd478d453a751c4halcanary    switch (colorType) {
180aa4ba90792a99eed96ac51006bd478d453a751c4halcanary        case kRGBA_8888_SkColorType:
181aa4ba90792a99eed96ac51006bd478d453a751c4halcanary        case kBGRA_8888_SkColorType: {
182aa4ba90792a99eed96ac51006bd478d453a751c4halcanary            SkASSERT(3 == pdf_color_component_count(colorType));
183db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary            SkAutoTMalloc<uint8_t> scanline(3 * bm.width());
184db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary            for (int y = 0; y < bm.height(); ++y) {
185aa4ba90792a99eed96ac51006bd478d453a751c4halcanary                const uint32_t* src = bm.getAddr32(0, y);
186db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary                uint8_t* dst = scanline.get();
187db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary                for (int x = 0; x < bm.width(); ++x) {
1887b9eabb392902e6e8f4206ba8aa041524258fd0fhalcanary                    if (alphaType == kPremul_SkAlphaType) {
1897b9eabb392902e6e8f4206ba8aa041524258fd0fhalcanary                        uint32_t color = *src++;
1907b9eabb392902e6e8f4206ba8aa041524258fd0fhalcanary                        U8CPU alpha = SkGetA32Component(color, colorType);
1917b9eabb392902e6e8f4206ba8aa041524258fd0fhalcanary                        if (alpha != SK_AlphaTRANSPARENT) {
1927b9eabb392902e6e8f4206ba8aa041524258fd0fhalcanary                            pmcolor_to_rgb24(color, dst, colorType);
1937b9eabb392902e6e8f4206ba8aa041524258fd0fhalcanary                        } else {
1947b9eabb392902e6e8f4206ba8aa041524258fd0fhalcanary                            get_neighbor_avg_color(bm, x, y, dst, colorType);
1957b9eabb392902e6e8f4206ba8aa041524258fd0fhalcanary                        }
1967b9eabb392902e6e8f4206ba8aa041524258fd0fhalcanary                        dst += 3;
197db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary                    } else {
1987b9eabb392902e6e8f4206ba8aa041524258fd0fhalcanary                        uint32_t color = *src++;
1997b9eabb392902e6e8f4206ba8aa041524258fd0fhalcanary                        *dst++ = SkGetR32Component(color, colorType);
2007b9eabb392902e6e8f4206ba8aa041524258fd0fhalcanary                        *dst++ = SkGetG32Component(color, colorType);
2017b9eabb392902e6e8f4206ba8aa041524258fd0fhalcanary                        *dst++ = SkGetB32Component(color, colorType);
202db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary                    }
203db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary                }
204db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary                out->write(scanline.get(), 3 * bm.width());
2051b5c604d9d344537941b11b136348edfc39f236chalcanary            }
206db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary            return;
2071b5c604d9d344537941b11b136348edfc39f236chalcanary        }
208db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary        case kRGB_565_SkColorType: {
209aa4ba90792a99eed96ac51006bd478d453a751c4halcanary            SkASSERT(3 == pdf_color_component_count(colorType));
210db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary            SkAutoTMalloc<uint8_t> scanline(3 * bm.width());
211db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary            for (int y = 0; y < bm.height(); ++y) {
212db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary                const uint16_t* src = bm.getAddr16(0, y);
213db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary                uint8_t* dst = scanline.get();
214db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary                for (int x = 0; x < bm.width(); ++x) {
215db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary                    U16CPU color565 = *src++;
216db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary                    *dst++ = SkPacked16ToR32(color565);
217db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary                    *dst++ = SkPacked16ToG32(color565);
218db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary                    *dst++ = SkPacked16ToB32(color565);
219db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary                }
220db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary                out->write(scanline.get(), 3 * bm.width());
221db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary            }
222db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary            return;
223db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary        }
224db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary        case kAlpha_8_SkColorType:
225aa4ba90792a99eed96ac51006bd478d453a751c4halcanary            SkASSERT(1 == pdf_color_component_count(colorType));
226db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary            fill_stream(out, '\x00', pixel_count(bm));
227db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary            return;
228db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary        case kGray_8_SkColorType:
229aa4ba90792a99eed96ac51006bd478d453a751c4halcanary            SkASSERT(1 == pdf_color_component_count(colorType));
230db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary            // these two formats need no transformation to serialize.
231db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary            for (int y = 0; y < bm.height(); ++y) {
232db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary                out->write(bm.getAddr8(0, y), bm.width());
233db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary            }
234db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary            return;
235db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary        case kUnknown_SkColorType:
236db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary        case kARGB_4444_SkColorType:
237db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary        default:
238db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary            SkDEBUGFAIL("unexpected color type");
2391b5c604d9d344537941b11b136348edfc39f236chalcanary    }
2401b5c604d9d344537941b11b136348edfc39f236chalcanary}
2411b5c604d9d344537941b11b136348edfc39f236chalcanary
242db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary////////////////////////////////////////////////////////////////////////////////
243db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary
244db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanarystatic void bitmap_alpha_to_a8(const SkBitmap& bitmap, SkWStream* out) {
245db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary    if (!bitmap.getPixels()) {
246db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary        fill_stream(out, '\xFF', pixel_count(bitmap));
2471b5c604d9d344537941b11b136348edfc39f236chalcanary        return;
2481b5c604d9d344537941b11b136348edfc39f236chalcanary    }
249db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary    SkBitmap copy;
2503f4671871fac8e5439440ce756d0666bc2a96f46Hal Canary    const SkBitmap& bm = supported_colortype(bitmap, &copy);
251aa4ba90792a99eed96ac51006bd478d453a751c4halcanary    SkColorType colorType = bm.colorType();
252aa4ba90792a99eed96ac51006bd478d453a751c4halcanary    switch (colorType) {
253aa4ba90792a99eed96ac51006bd478d453a751c4halcanary        case kRGBA_8888_SkColorType:
254aa4ba90792a99eed96ac51006bd478d453a751c4halcanary        case kBGRA_8888_SkColorType: {
255db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary            SkAutoTMalloc<uint8_t> scanline(bm.width());
256db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary            for (int y = 0; y < bm.height(); ++y) {
257db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary                uint8_t* dst = scanline.get();
258db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary                const SkPMColor* src = bm.getAddr32(0, y);
259db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary                for (int x = 0; x < bm.width(); ++x) {
260aa4ba90792a99eed96ac51006bd478d453a751c4halcanary                    *dst++ = SkGetA32Component(*src++, colorType);
261db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary                }
262db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary                out->write(scanline.get(), bm.width());
263db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary            }
264db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary            return;
2651b5c604d9d344537941b11b136348edfc39f236chalcanary        }
266db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary        case kAlpha_8_SkColorType:
267db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary            for (int y = 0; y < bm.height(); ++y) {
268db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary                out->write(bm.getAddr8(0, y), bm.width());
269db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary            }
270db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary            return;
271db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary        case kRGB_565_SkColorType:
272db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary        case kGray_8_SkColorType:
273db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary            SkDEBUGFAIL("color type has no alpha");
274db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary            return;
275db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary        case kARGB_4444_SkColorType:
276db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary            SkDEBUGFAIL("4444 color type should have been converted to N32");
277db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary            return;
278db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary        case kUnknown_SkColorType:
279db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary        default:
280db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary            SkDEBUGFAIL("unexpected color type");
2811b5c604d9d344537941b11b136348edfc39f236chalcanary    }
2821b5c604d9d344537941b11b136348edfc39f236chalcanary}
2831b5c604d9d344537941b11b136348edfc39f236chalcanary
2847a14b310d6c618fa2151d93a43b29f9599adc32ahalcanarystatic void emit_image_xobject(SkWStream* stream,
2857a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary                               const SkImage* image,
2867a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary                               bool alpha,
2878103a34300c5de2e85793a96c4738a33fc6eb46dhalcanary                               const sk_sp<SkPDFObject>& smask,
288530032a18e373ee673ae96fdbfa1fae6292f8f08halcanary                               const SkPDFObjNumMap& objNumMap) {
2897a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary    SkBitmap bitmap;
2904f29c20f20ce62150998786be8b9f8a81a901d72Hal Canary    if (!SkPDFUtils::ToBitmap(image, &bitmap)) {
2914f29c20f20ce62150998786be8b9f8a81a901d72Hal Canary        // no pixels or wrong size: fill with zeros.
2924f29c20f20ce62150998786be8b9f8a81a901d72Hal Canary        bitmap.setInfo(SkImageInfo::MakeN32(image->width(), image->height(), image->alphaType()));
2934f29c20f20ce62150998786be8b9f8a81a901d72Hal Canary    }
29437c46cad21632cfc1411b08d73af37a1fffe2944halcanary
29537c46cad21632cfc1411b08d73af37a1fffe2944halcanary    // Write to a temporary buffer to get the compressed length.
29637c46cad21632cfc1411b08d73af37a1fffe2944halcanary    SkDynamicMemoryWStream buffer;
29737c46cad21632cfc1411b08d73af37a1fffe2944halcanary    SkDeflateWStream deflateWStream(&buffer);
2987a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary    if (alpha) {
2997a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary        bitmap_alpha_to_a8(bitmap, &deflateWStream);
3007a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary    } else {
3017a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary        bitmap_to_pdf_pixels(bitmap, &deflateWStream);
3027a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary    }
3036fee59b514c5f7b7ff34d63b294759dd0c1d4858Hal Canary    deflateWStream.finalize();  // call before buffer.bytesWritten().
30437c46cad21632cfc1411b08d73af37a1fffe2944halcanary
3051b5c604d9d344537941b11b136348edfc39f236chalcanary    SkPDFDict pdfDict("XObject");
3061b5c604d9d344537941b11b136348edfc39f236chalcanary    pdfDict.insertName("Subtype", "Image");
3077a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary    pdfDict.insertInt("Width", bitmap.width());
3087a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary    pdfDict.insertInt("Height", bitmap.height());
3097a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary    if (alpha) {
3107a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary        pdfDict.insertName("ColorSpace", "DeviceGray");
3117a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary    } else if (1 == pdf_color_component_count(bitmap.colorType())) {
312db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary        pdfDict.insertName("ColorSpace", "DeviceGray");
313db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary    } else {
314db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary        pdfDict.insertName("ColorSpace", "DeviceRGB");
315db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary    }
3167a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary    if (smask) {
3178103a34300c5de2e85793a96c4738a33fc6eb46dhalcanary        pdfDict.insertObjRef("SMask", smask);
3181b5c604d9d344537941b11b136348edfc39f236chalcanary    }
3197a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary    pdfDict.insertInt("BitsPerComponent", 8);
320db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary    pdfDict.insertName("Filter", "FlateDecode");
3216fee59b514c5f7b7ff34d63b294759dd0c1d4858Hal Canary    pdfDict.insertInt("Length", buffer.bytesWritten());
322530032a18e373ee673ae96fdbfa1fae6292f8f08halcanary    pdfDict.emitObject(stream, objNumMap);
32337c46cad21632cfc1411b08d73af37a1fffe2944halcanary
32437c46cad21632cfc1411b08d73af37a1fffe2944halcanary    pdf_stream_begin(stream);
3256fee59b514c5f7b7ff34d63b294759dd0c1d4858Hal Canary    buffer.writeToAndReset(stream);
32637c46cad21632cfc1411b08d73af37a1fffe2944halcanary    pdf_stream_end(stream);
3271b5c604d9d344537941b11b136348edfc39f236chalcanary}
3281b5c604d9d344537941b11b136348edfc39f236chalcanary
3291b5c604d9d344537941b11b136348edfc39f236chalcanary////////////////////////////////////////////////////////////////////////////////
330db0dcc7436375e5d59c27f9011f09b64de407c9dhalcanary
3317a14b310d6c618fa2151d93a43b29f9599adc32ahalcanarynamespace {
3327a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary// This SkPDFObject only outputs the alpha layer of the given bitmap.
33370d1554d8ea08ddb887550f98b9cfd0afd395d65halcanaryclass PDFAlphaBitmap final : public SkPDFObject {
3347a14b310d6c618fa2151d93a43b29f9599adc32ahalcanarypublic:
335a50151dcb5a0b8bfdef383e363e519c91d2d2c7ahalcanary    PDFAlphaBitmap(sk_sp<SkImage> image) : fImage(std::move(image)) { SkASSERT(fImage); }
3367a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary    void emitObject(SkWStream*  stream,
337530032a18e373ee673ae96fdbfa1fae6292f8f08halcanary                    const SkPDFObjNumMap& objNumMap) const override {
338bae235eb07cdfeb6dd92efa2b2143fa9e91d9d04halcanary        SkASSERT(fImage);
339530032a18e373ee673ae96fdbfa1fae6292f8f08halcanary        emit_image_xobject(stream, fImage.get(), true, nullptr, objNumMap);
3401b5c604d9d344537941b11b136348edfc39f236chalcanary    }
341bae235eb07cdfeb6dd92efa2b2143fa9e91d9d04halcanary    void drop() override { fImage = nullptr; }
3427a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary
3437a14b310d6c618fa2151d93a43b29f9599adc32ahalcanaryprivate:
344a50151dcb5a0b8bfdef383e363e519c91d2d2c7ahalcanary    sk_sp<SkImage> fImage;
3457a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary};
3467a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary
3477a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary}  // namespace
3487a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary
3497a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary////////////////////////////////////////////////////////////////////////////////
3507a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary
3517a14b310d6c618fa2151d93a43b29f9599adc32ahalcanarynamespace {
35270d1554d8ea08ddb887550f98b9cfd0afd395d65halcanaryclass PDFDefaultBitmap final : public SkPDFObject {
3537a14b310d6c618fa2151d93a43b29f9599adc32ahalcanarypublic:
35434422610ac22adceeabb66023120f27b96cae953halcanary    void emitObject(SkWStream* stream,
355530032a18e373ee673ae96fdbfa1fae6292f8f08halcanary                    const SkPDFObjNumMap& objNumMap) const override {
356bae235eb07cdfeb6dd92efa2b2143fa9e91d9d04halcanary        SkASSERT(fImage);
357530032a18e373ee673ae96fdbfa1fae6292f8f08halcanary        emit_image_xobject(stream, fImage.get(), false, fSMask, objNumMap);
3587a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary    }
359530032a18e373ee673ae96fdbfa1fae6292f8f08halcanary    void addResources(SkPDFObjNumMap* catalog) const override {
360530032a18e373ee673ae96fdbfa1fae6292f8f08halcanary        catalog->addObjectRecursively(fSMask.get());
3617a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary    }
362bae235eb07cdfeb6dd92efa2b2143fa9e91d9d04halcanary    void drop() override { fImage = nullptr; fSMask = nullptr; }
363a50151dcb5a0b8bfdef383e363e519c91d2d2c7ahalcanary    PDFDefaultBitmap(sk_sp<SkImage> image, sk_sp<SkPDFObject> smask)
364a50151dcb5a0b8bfdef383e363e519c91d2d2c7ahalcanary        : fImage(std::move(image)), fSMask(std::move(smask)) { SkASSERT(fImage); }
3657a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary
3667a14b310d6c618fa2151d93a43b29f9599adc32ahalcanaryprivate:
367a50151dcb5a0b8bfdef383e363e519c91d2d2c7ahalcanary    sk_sp<SkImage> fImage;
368bae235eb07cdfeb6dd92efa2b2143fa9e91d9d04halcanary    sk_sp<SkPDFObject> fSMask;
3697a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary};
3707a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary}  // namespace
3717a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary
3727a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary////////////////////////////////////////////////////////////////////////////////
3731b5c604d9d344537941b11b136348edfc39f236chalcanary
374a8448bc3dfe0f2e768838b4416fb3ebf823b694ehalcanarynamespace {
375a8448bc3dfe0f2e768838b4416fb3ebf823b694ehalcanary/**
3767a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary *  This PDFObject assumes that its constructor was handed YUV or
3777a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary *  Grayscale JFIF Jpeg-encoded data that can be directly embedded
3787a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary *  into a PDF.
379a8448bc3dfe0f2e768838b4416fb3ebf823b694ehalcanary */
38070d1554d8ea08ddb887550f98b9cfd0afd395d65halcanaryclass PDFJpegBitmap final : public SkPDFObject {
381a8448bc3dfe0f2e768838b4416fb3ebf823b694ehalcanarypublic:
3827a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary    SkISize fSize;
38348810a023705ffac466adb93efdb3861cf2e197ahalcanary    sk_sp<SkData> fData;
38496287f7af7ff6aaa48b8d28ec6b7b79836da2d7chalcanary    bool fIsYUV;
3857a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary    PDFJpegBitmap(SkISize size, SkData* data, bool isYUV)
386bae235eb07cdfeb6dd92efa2b2143fa9e91d9d04halcanary        : fSize(size), fData(SkRef(data)), fIsYUV(isYUV) { SkASSERT(data); }
387530032a18e373ee673ae96fdbfa1fae6292f8f08halcanary    void emitObject(SkWStream*, const SkPDFObjNumMap&) const override;
388bae235eb07cdfeb6dd92efa2b2143fa9e91d9d04halcanary    void drop() override { fData = nullptr; }
389a8448bc3dfe0f2e768838b4416fb3ebf823b694ehalcanary};
390a8448bc3dfe0f2e768838b4416fb3ebf823b694ehalcanary
391a8448bc3dfe0f2e768838b4416fb3ebf823b694ehalcanaryvoid PDFJpegBitmap::emitObject(SkWStream* stream,
392530032a18e373ee673ae96fdbfa1fae6292f8f08halcanary                               const SkPDFObjNumMap& objNumMap) const {
393bae235eb07cdfeb6dd92efa2b2143fa9e91d9d04halcanary    SkASSERT(fData);
394a8448bc3dfe0f2e768838b4416fb3ebf823b694ehalcanary    SkPDFDict pdfDict("XObject");
395a8448bc3dfe0f2e768838b4416fb3ebf823b694ehalcanary    pdfDict.insertName("Subtype", "Image");
3967a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary    pdfDict.insertInt("Width", fSize.width());
3977a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary    pdfDict.insertInt("Height", fSize.height());
39896287f7af7ff6aaa48b8d28ec6b7b79836da2d7chalcanary    if (fIsYUV) {
39996287f7af7ff6aaa48b8d28ec6b7b79836da2d7chalcanary        pdfDict.insertName("ColorSpace", "DeviceRGB");
40096287f7af7ff6aaa48b8d28ec6b7b79836da2d7chalcanary    } else {
40196287f7af7ff6aaa48b8d28ec6b7b79836da2d7chalcanary        pdfDict.insertName("ColorSpace", "DeviceGray");
40296287f7af7ff6aaa48b8d28ec6b7b79836da2d7chalcanary    }
403a8448bc3dfe0f2e768838b4416fb3ebf823b694ehalcanary    pdfDict.insertInt("BitsPerComponent", 8);
404a8448bc3dfe0f2e768838b4416fb3ebf823b694ehalcanary    pdfDict.insertName("Filter", "DCTDecode");
405a8448bc3dfe0f2e768838b4416fb3ebf823b694ehalcanary    pdfDict.insertInt("ColorTransform", 0);
406a8448bc3dfe0f2e768838b4416fb3ebf823b694ehalcanary    pdfDict.insertInt("Length", SkToInt(fData->size()));
407530032a18e373ee673ae96fdbfa1fae6292f8f08halcanary    pdfDict.emitObject(stream, objNumMap);
408a8448bc3dfe0f2e768838b4416fb3ebf823b694ehalcanary    pdf_stream_begin(stream);
409a8448bc3dfe0f2e768838b4416fb3ebf823b694ehalcanary    stream->write(fData->data(), fData->size());
410a8448bc3dfe0f2e768838b4416fb3ebf823b694ehalcanary    pdf_stream_end(stream);
411a8448bc3dfe0f2e768838b4416fb3ebf823b694ehalcanary}
412a8448bc3dfe0f2e768838b4416fb3ebf823b694ehalcanary}  // namespace
413a8448bc3dfe0f2e768838b4416fb3ebf823b694ehalcanary
414a8448bc3dfe0f2e768838b4416fb3ebf823b694ehalcanary////////////////////////////////////////////////////////////////////////////////
415a8448bc3dfe0f2e768838b4416fb3ebf823b694ehalcanary
416a50151dcb5a0b8bfdef383e363e519c91d2d2c7ahalcanarysk_sp<SkPDFObject> SkPDFCreateBitmapObject(sk_sp<SkImage> image,
417a50151dcb5a0b8bfdef383e363e519c91d2d2c7ahalcanary                                           SkPixelSerializer* pixelSerializer) {
418a50151dcb5a0b8bfdef383e363e519c91d2d2c7ahalcanary    SkASSERT(image);
4196409f84fc3ae5e3b2df9eb0a900957fce404ad5cMike Reed    sk_sp<SkData> data = image->refEncodedData();
4207a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary    SkJFIFInfo info;
421fcad44bbb1e0384620e7b738a0f5904c940a6861halcanary    if (data && SkIsJFIF(data.get(), &info) &&
4227363e13a07f8b6a9d4ba82ff7b13526f0a89eaeehalcanary        (!pixelSerializer ||
4237363e13a07f8b6a9d4ba82ff7b13526f0a89eaeehalcanary         pixelSerializer->useEncodedData(data->data(), data->size()))) {
4247363e13a07f8b6a9d4ba82ff7b13526f0a89eaeehalcanary        // If there is a SkPixelSerializer, give it a chance to
4257363e13a07f8b6a9d4ba82ff7b13526f0a89eaeehalcanary        // re-encode the JPEG with more compression by returning false
4267363e13a07f8b6a9d4ba82ff7b13526f0a89eaeehalcanary        // from useEncodedData.
4277a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary        bool yuv = info.fType == SkJFIFInfo::kYCbCr;
4287a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary        if (info.fSize == image->dimensions()) {  // Sanity check.
4297a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary            // hold on to data, not image.
4307a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary            #ifdef SK_PDF_IMAGE_STATS
4317a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary            gJpegImageObjects.fetch_add(1);
4327a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary            #endif
433a50151dcb5a0b8bfdef383e363e519c91d2d2c7ahalcanary            return sk_make_sp<PDFJpegBitmap>(info.fSize, data.get(), yuv);
434a8448bc3dfe0f2e768838b4416fb3ebf823b694ehalcanary        }
435a8448bc3dfe0f2e768838b4416fb3ebf823b694ehalcanary    }
436712fdf7603c62820b21174da9b0a2071c174936bhalcanary
437712fdf7603c62820b21174da9b0a2071c174936bhalcanary    if (pixelSerializer) {
438712fdf7603c62820b21174da9b0a2071c174936bhalcanary        SkBitmap bm;
4394edb5d219eb99aa1e8fbe5e37260d3b34314e54bMike Reed        SkPixmap pmap;
4404f29c20f20ce62150998786be8b9f8a81a901d72Hal Canary        if (SkPDFUtils::ToBitmap(image.get(), &bm) && bm.peekPixels(&pmap)) {
4416409f84fc3ae5e3b2df9eb0a900957fce404ad5cMike Reed            data = pixelSerializer->encodeToData(pmap);
442fcad44bbb1e0384620e7b738a0f5904c940a6861halcanary            if (data && SkIsJFIF(data.get(), &info)) {
443712fdf7603c62820b21174da9b0a2071c174936bhalcanary                bool yuv = info.fType == SkJFIFInfo::kYCbCr;
444712fdf7603c62820b21174da9b0a2071c174936bhalcanary                if (info.fSize == image->dimensions()) {  // Sanity check.
445a50151dcb5a0b8bfdef383e363e519c91d2d2c7ahalcanary                    return sk_make_sp<PDFJpegBitmap>(info.fSize, data.get(), yuv);
446712fdf7603c62820b21174da9b0a2071c174936bhalcanary                }
447712fdf7603c62820b21174da9b0a2071c174936bhalcanary            }
448712fdf7603c62820b21174da9b0a2071c174936bhalcanary        }
449712fdf7603c62820b21174da9b0a2071c174936bhalcanary    }
450712fdf7603c62820b21174da9b0a2071c174936bhalcanary
451a50151dcb5a0b8bfdef383e363e519c91d2d2c7ahalcanary    sk_sp<SkPDFObject> smask;
452a50151dcb5a0b8bfdef383e363e519c91d2d2c7ahalcanary    if (!image_compute_is_opaque(image.get())) {
453a50151dcb5a0b8bfdef383e363e519c91d2d2c7ahalcanary        smask = sk_make_sp<PDFAlphaBitmap>(image);
454a50151dcb5a0b8bfdef383e363e519c91d2d2c7ahalcanary    }
4557a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary    #ifdef SK_PDF_IMAGE_STATS
4567a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary    gRegularImageObjects.fetch_add(1);
4577a14b310d6c618fa2151d93a43b29f9599adc32ahalcanary    #endif
458a50151dcb5a0b8bfdef383e363e519c91d2d2c7ahalcanary    return sk_make_sp<PDFDefaultBitmap>(std::move(image), std::move(smask));
4591b5c604d9d344537941b11b136348edfc39f236chalcanary}
460