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