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