 Chromium Code Reviews
 Chromium Code Reviews| Index: src/pdf/SkPDFImage.cpp | 
| diff --git a/src/pdf/SkPDFImage.cpp b/src/pdf/SkPDFImage.cpp | 
| index a5cb4c20d1b9e187948cc6654d590b219df4d686..d4066aa6597f3db9407d534cb39a46577ee7d9a4 100644 | 
| --- a/src/pdf/SkPDFImage.cpp | 
| +++ b/src/pdf/SkPDFImage.cpp | 
| @@ -10,6 +10,8 @@ | 
| #include "SkBitmap.h" | 
| #include "SkColor.h" | 
| #include "SkColorPriv.h" | 
| +#include "SkData.h" | 
| +#include "SkFlate.h" | 
| #include "SkPDFCatalog.h" | 
| #include "SkRect.h" | 
| #include "SkStream.h" | 
| @@ -18,18 +20,58 @@ | 
| namespace { | 
| 
vandebo (ex-Chrome)
2013/08/21 22:37:17
Looks like you can probably remove the anonymous n
 
ducky
2013/08/22 03:48:06
Done.
 | 
| -void extractImageData(const SkBitmap& bitmap, const SkIRect& srcRect, | 
| - SkStream** imageData, SkStream** alphaData) { | 
| 
vandebo (ex-Chrome)
2013/08/21 22:37:17
We talked about the different cases the other day:
 
ducky
2013/08/22 03:48:06
Done. I think the merged one is less elegant, but
 | 
| - SkMemoryStream* image = NULL; | 
| - SkMemoryStream* alpha = NULL; | 
| - bool hasAlpha = false; | 
| - bool isTransparent = false; | 
| +#define kNoColorTransform 0 | 
| 
vandebo (ex-Chrome)
2013/08/21 22:37:17
const int kNoColorTransform = 0;
 
ducky
2013/08/22 03:48:06
Done.
 | 
| +static bool skip_compression(SkPDFCatalog* catalog) { | 
| + return SkToBool(catalog->getDocumentFlags() & | 
| + SkPDFDocument::kFavorSpeedOverSize_Flags); | 
| +} | 
| + | 
| +static size_t get_row_bytes(const SkBitmap& bitmap, | 
| + const SkIRect& srcRect) { | 
| + switch (bitmap.getConfig()) { | 
| + case SkBitmap::kIndex8_Config: | 
| + return srcRect.width(); | 
| + case SkBitmap::kARGB_4444_Config: | 
| + return (srcRect.width() * 3 + 1) / 2; | 
| + case SkBitmap::kRGB_565_Config: | 
| + return srcRect.width() * 3; | 
| + case SkBitmap::kARGB_8888_Config: | 
| + return srcRect.width() * 3; | 
| + case SkBitmap::kA1_Config: | 
| + case SkBitmap::kA8_Config: | 
| + return 1; | 
| + default: | 
| + SkASSERT(false); | 
| + return 0; | 
| + } | 
| +} | 
| + | 
| +static size_t get_uncompressed_size(const SkBitmap& bitmap, | 
| + const SkIRect& srcRect) { | 
| + switch (bitmap.getConfig()) { | 
| + case SkBitmap::kIndex8_Config: | 
| + case SkBitmap::kARGB_4444_Config: | 
| + case SkBitmap::kRGB_565_Config: | 
| + case SkBitmap::kARGB_8888_Config: | 
| + return get_row_bytes(bitmap, srcRect) * srcRect.height(); | 
| + case SkBitmap::kA1_Config: | 
| + case SkBitmap::kA8_Config: | 
| + return 1; | 
| + default: | 
| + SkASSERT(false); | 
| + return 0; | 
| + } | 
| +} | 
| + | 
| +static SkStream* extract_image_data(const SkBitmap& bitmap, | 
| + const SkIRect& srcRect) { | 
| + const int rowBytes = get_row_bytes(bitmap, srcRect); | 
| + SkMemoryStream* image = new SkMemoryStream(get_uncompressed_size(bitmap, | 
| + srcRect)); | 
| bitmap.lockPixels(); | 
| switch (bitmap.getConfig()) { | 
| case SkBitmap::kIndex8_Config: { | 
| - const int rowBytes = srcRect.width(); | 
| - image = new SkMemoryStream(rowBytes * srcRect.height()); | 
| uint8_t* dst = (uint8_t*)image->getMemoryBase(); | 
| for (int y = srcRect.fTop; y < srcRect.fBottom; y++) { | 
| memcpy(dst, bitmap.getAddr8(srcRect.fLeft, y), rowBytes); | 
| @@ -38,13 +80,7 @@ void extractImageData(const SkBitmap& bitmap, const SkIRect& srcRect, | 
| break; | 
| } | 
| case SkBitmap::kARGB_4444_Config: { | 
| - isTransparent = true; | 
| - const int rowBytes = (srcRect.width() * 3 + 1) / 2; | 
| - const int alphaRowBytes = (srcRect.width() + 1) / 2; | 
| - image = new SkMemoryStream(rowBytes * srcRect.height()); | 
| - alpha = new SkMemoryStream(alphaRowBytes * srcRect.height()); | 
| uint8_t* dst = (uint8_t*)image->getMemoryBase(); | 
| - uint8_t* alphaDst = (uint8_t*)alpha->getMemoryBase(); | 
| for (int y = srcRect.fTop; y < srcRect.fBottom; y++) { | 
| uint16_t* src = bitmap.getAddr16(0, y); | 
| int x; | 
| @@ -56,36 +92,17 @@ void extractImageData(const SkBitmap& bitmap, const SkIRect& srcRect, | 
| dst[2] = (SkGetPackedG4444(src[x + 1]) << 4) | | 
| SkGetPackedB4444(src[x + 1]); | 
| dst += 3; | 
| - alphaDst[0] = (SkGetPackedA4444(src[x]) << 4) | | 
| - SkGetPackedA4444(src[x + 1]); | 
| - if (alphaDst[0] != 0xFF) { | 
| - hasAlpha = true; | 
| - } | 
| - if (alphaDst[0]) { | 
| - isTransparent = false; | 
| - } | 
| - alphaDst++; | 
| } | 
| if (srcRect.width() & 1) { | 
| dst[0] = (SkGetPackedR4444(src[x]) << 4) | | 
| SkGetPackedG4444(src[x]); | 
| dst[1] = (SkGetPackedB4444(src[x]) << 4); | 
| dst += 2; | 
| - alphaDst[0] = (SkGetPackedA4444(src[x]) << 4); | 
| - if (alphaDst[0] != 0xF0) { | 
| - hasAlpha = true; | 
| - } | 
| - if (alphaDst[0] & 0xF0) { | 
| - isTransparent = false; | 
| - } | 
| - alphaDst++; | 
| } | 
| } | 
| break; | 
| } | 
| case SkBitmap::kRGB_565_Config: { | 
| - const int rowBytes = srcRect.width() * 3; | 
| - image = new SkMemoryStream(rowBytes * srcRect.height()); | 
| uint8_t* dst = (uint8_t*)image->getMemoryBase(); | 
| for (int y = srcRect.fTop; y < srcRect.fBottom; y++) { | 
| uint16_t* src = bitmap.getAddr16(0, y); | 
| @@ -99,12 +116,7 @@ void extractImageData(const SkBitmap& bitmap, const SkIRect& srcRect, | 
| break; | 
| } | 
| case SkBitmap::kARGB_8888_Config: { | 
| - isTransparent = true; | 
| - const int rowBytes = srcRect.width() * 3; | 
| - image = new SkMemoryStream(rowBytes * srcRect.height()); | 
| - alpha = new SkMemoryStream(srcRect.width() * srcRect.height()); | 
| uint8_t* dst = (uint8_t*)image->getMemoryBase(); | 
| - uint8_t* alphaDst = (uint8_t*)alpha->getMemoryBase(); | 
| for (int y = srcRect.fTop; y < srcRect.fBottom; y++) { | 
| uint32_t* src = bitmap.getAddr32(0, y); | 
| for (int x = srcRect.fLeft; x < srcRect.fRight; x++) { | 
| @@ -112,12 +124,79 @@ void extractImageData(const SkBitmap& bitmap, const SkIRect& srcRect, | 
| dst[1] = SkGetPackedG32(src[x]); | 
| dst[2] = SkGetPackedB32(src[x]); | 
| dst += 3; | 
| + } | 
| + } | 
| + break; | 
| + } | 
| + case SkBitmap::kA1_Config: | 
| + case SkBitmap::kA8_Config: { | 
| + ((uint8_t*)image->getMemoryBase())[0] = 0; | 
| 
vandebo (ex-Chrome)
2013/08/21 22:37:17
Sk_ColorBLACK?
 
ducky
2013/08/22 03:48:06
No can do... SK_ColorBLACK is a 4-byte value conta
 | 
| + break; | 
| + } | 
| + default: | 
| + SkASSERT(false); | 
| + } | 
| + bitmap.unlockPixels(); | 
| + | 
| + return image; | 
| +} | 
| + | 
| +// Extract the alpha data from a SkBitmap and output it in a SkStream. | 
| +// alphaData may be NULL if there was no alpha data to extract (image | 
| +// completely opaque). | 
| +// isTransparent outputs true if the alpha is completely transparent. | 
| +static SkStream* extract_alpha_data(const SkBitmap& bitmap, | 
| + const SkIRect& srcRect, | 
| + bool* isTransparent) { | 
| + SkMemoryStream* alpha = NULL; | 
| + bool hasAlpha = false; | 
| + *isTransparent = true; | 
| + | 
| + bitmap.lockPixels(); | 
| + switch (bitmap.getConfig()) { | 
| + case SkBitmap::kARGB_4444_Config: { | 
| + const int alphaRowBytes = (srcRect.width() + 1) / 2; | 
| + alpha = new SkMemoryStream(alphaRowBytes * srcRect.height()); | 
| + uint8_t* alphaDst = (uint8_t*)alpha->getMemoryBase(); | 
| + for (int y = srcRect.fTop; y < srcRect.fBottom; y++) { | 
| + uint16_t* src = bitmap.getAddr16(0, y); | 
| + int x; | 
| + for (x = srcRect.fLeft; x + 1 < srcRect.fRight; x += 2) { | 
| + alphaDst[0] = (SkGetPackedA4444(src[x]) << 4) | | 
| + SkGetPackedA4444(src[x + 1]); | 
| + if (alphaDst[0] != SK_AlphaOPAQUE) { | 
| + hasAlpha = true; | 
| + } | 
| + if (alphaDst[0] != SK_AlphaTRANSPARENT) { | 
| + *isTransparent = false; | 
| + } | 
| + alphaDst++; | 
| + } | 
| + if (srcRect.width() & 1) { | 
| + alphaDst[0] = (SkGetPackedA4444(src[x]) << 4); | 
| + if (alphaDst[0] != (SK_AlphaOPAQUE & 0xF0)) { | 
| + hasAlpha = true; | 
| + } | 
| + if (alphaDst[0] != (SK_AlphaTRANSPARENT & 0xF0)) { | 
| + *isTransparent = false; | 
| + } | 
| + alphaDst++; | 
| + } | 
| + } | 
| + break; | 
| + } | 
| + case SkBitmap::kARGB_8888_Config: { | 
| + alpha = new SkMemoryStream(srcRect.width() * srcRect.height()); | 
| + uint8_t* alphaDst = (uint8_t*)alpha->getMemoryBase(); | 
| + for (int y = srcRect.fTop; y < srcRect.fBottom; y++) { | 
| + uint32_t* src = bitmap.getAddr32(0, y); | 
| + for (int x = srcRect.fLeft; x < srcRect.fRight; x++) { | 
| alphaDst[0] = SkGetPackedA32(src[x]); | 
| - if (alphaDst[0] != 0xFF) { | 
| + if (alphaDst[0] != SK_AlphaOPAQUE) { | 
| hasAlpha = true; | 
| } | 
| - if (alphaDst[0]) { | 
| - isTransparent = false; | 
| + if (alphaDst[0] != SK_AlphaTRANSPARENT) { | 
| + *isTransparent = false; | 
| } | 
| alphaDst++; | 
| } | 
| @@ -125,10 +204,6 @@ void extractImageData(const SkBitmap& bitmap, const SkIRect& srcRect, | 
| break; | 
| } | 
| case SkBitmap::kA1_Config: { | 
| - isTransparent = true; | 
| - image = new SkMemoryStream(1); | 
| - ((uint8_t*)image->getMemoryBase())[0] = 0; | 
| - | 
| const int alphaRowBytes = (srcRect.width() + 7) / 8; | 
| alpha = new SkMemoryStream(alphaRowBytes * srcRect.height()); | 
| uint8_t* alphaDst = (uint8_t*)alpha->getMemoryBase(); | 
| @@ -145,11 +220,13 @@ void extractImageData(const SkBitmap& bitmap, const SkIRect& srcRect, | 
| } else { | 
| alphaDst[0] = src[x / 8]; | 
| } | 
| - if (x + 7 < srcRect.fRight && alphaDst[0] != 0xFF) { | 
| + if (x + 7 < srcRect.fRight && | 
| + alphaDst[0] != SK_AlphaOPAQUE) { | 
| hasAlpha = true; | 
| } | 
| - if (x + 7 < srcRect.fRight && alphaDst[0]) { | 
| - isTransparent = false; | 
| + if (x + 7 < srcRect.fRight && | 
| + alphaDst[0] != SK_AlphaTRANSPARENT) { | 
| + *isTransparent = false; | 
| } | 
| alphaDst++; | 
| } | 
| @@ -157,20 +234,18 @@ void extractImageData(const SkBitmap& bitmap, const SkIRect& srcRect, | 
| // last byte of alphaDst. | 
| // width mod 8 == 1 -> 0x80 ... width mod 8 == 7 -> 0xFE | 
| uint8_t mask = ~((1 << (8 - (srcRect.width() % 8))) - 1); | 
| - if (srcRect.width() % 8 && (alphaDst[-1] & mask) != mask) { | 
| + if (srcRect.width() % 8 && | 
| + ((alphaDst[-1] & mask) != (SK_AlphaOPAQUE & mask))) { | 
| hasAlpha = true; | 
| } | 
| - if (srcRect.width() % 8 && (alphaDst[-1] & mask)) { | 
| - isTransparent = false; | 
| + if (srcRect.width() % 8 && | 
| + ((alphaDst[-1] & mask) != (SK_AlphaTRANSPARENT & mask))) { | 
| + *isTransparent = false; | 
| } | 
| } | 
| break; | 
| } | 
| case SkBitmap::kA8_Config: { | 
| - isTransparent = true; | 
| - image = new SkMemoryStream(1); | 
| - ((uint8_t*)image->getMemoryBase())[0] = 0; | 
| - | 
| const int alphaRowBytes = srcRect.width(); | 
| alpha = new SkMemoryStream(alphaRowBytes * srcRect.height()); | 
| uint8_t* alphaDst = (uint8_t*)alpha->getMemoryBase(); | 
| @@ -178,32 +253,32 @@ void extractImageData(const SkBitmap& bitmap, const SkIRect& srcRect, | 
| uint8_t* src = bitmap.getAddr8(0, y); | 
| for (int x = srcRect.fLeft; x < srcRect.fRight; x++) { | 
| alphaDst[0] = src[x]; | 
| - if (alphaDst[0] != 0xFF) { | 
| + if (alphaDst[0] != SK_AlphaOPAQUE) { | 
| hasAlpha = true; | 
| } | 
| - if (alphaDst[0]) { | 
| - isTransparent = false; | 
| + if (alphaDst[0] != SK_AlphaTRANSPARENT) { | 
| + *isTransparent = false; | 
| } | 
| alphaDst++; | 
| } | 
| } | 
| break; | 
| } | 
| + case SkBitmap::kRGB_565_Config: | 
| + case SkBitmap::kIndex8_Config: { | 
| + *isTransparent = false; | 
| + break; | 
| + } | 
| default: | 
| SkASSERT(false); | 
| } | 
| bitmap.unlockPixels(); | 
| - if (isTransparent) { | 
| - SkSafeUnref(image); | 
| - } else { | 
| - *imageData = image; | 
| - } | 
| - | 
| - if (isTransparent || !hasAlpha) { | 
| + if (!hasAlpha || *isTransparent) { | 
| SkSafeUnref(alpha); | 
| + return NULL; | 
| } else { | 
| - *alphaData = alpha; | 
| + return alpha; | 
| } | 
| } | 
| @@ -238,26 +313,14 @@ SkPDFImage* SkPDFImage::CreateImage(const SkBitmap& bitmap, | 
| if (bitmap.getConfig() == SkBitmap::kNo_Config) { | 
| return NULL; | 
| } | 
| + SkPDFImage* image = SkNEW_ARGS(SkPDFImage, (bitmap, srcRect, encoder)); | 
| - SkStream* imageData = NULL; | 
| - SkStream* alphaData = NULL; | 
| - extractImageData(bitmap, srcRect, &imageData, &alphaData); | 
| - SkAutoUnref unrefImageData(imageData); | 
| - SkAutoUnref unrefAlphaData(alphaData); | 
| - if (!imageData) { | 
| - SkASSERT(!alphaData); | 
| + if (image->isEmpty()) { | 
| 
vandebo (ex-Chrome)
2013/08/21 22:37:17
isEmpty just checks srcRect.  1) I think that's a
 
ducky
2013/08/22 03:48:06
Good point, it probably does change behavior.
What
 | 
| + image->unref(); | 
| return NULL; | 
| + } else { | 
| + return image; | 
| } | 
| - | 
| - SkPDFImage* image = | 
| - SkNEW_ARGS(SkPDFImage, (imageData, bitmap, srcRect, false, encoder)); | 
| - | 
| - if (alphaData != NULL) { | 
| - // Don't try to use DCT compression with alpha because alpha is small | 
| - // anyway and it could lead to artifacts. | 
| - image->addSMask(SkNEW_ARGS(SkPDFImage, (alphaData, bitmap, srcRect, true, NULL)))->unref(); | 
| - } | 
| - return image; | 
| } | 
| SkPDFImage::~SkPDFImage() { | 
| @@ -276,51 +339,89 @@ void SkPDFImage::getResources(const SkTSet<SkPDFObject*>& knownResourceObjects, | 
| GetResourcesHelper(&fResources, knownResourceObjects, newResourceObjects); | 
| } | 
| -SkPDFImage::SkPDFImage(SkStream* imageData, | 
| - const SkBitmap& bitmap, | 
| +SkPDFImage::SkPDFImage(const SkBitmap& bitmap, | 
| const SkIRect& srcRect, | 
| - bool doingAlpha, | 
| EncodeToDCTStream encoder) | 
| - : SkPDFImageStream(imageData, bitmap, srcRect, encoder) { | 
| - SkBitmap::Config config = bitmap.getConfig(); | 
| - bool alphaOnly = (config == SkBitmap::kA1_Config || | 
| - config == SkBitmap::kA8_Config); | 
| + : fBitmap(bitmap), | 
| + fSrcRect(srcRect), | 
| + fEncoder(encoder) { | 
| + bool isTransparent; | 
| + SkAutoTUnref<SkStream> alphaData(extract_alpha_data(bitmap, srcRect, | 
| + &isTransparent)); | 
| + if (isTransparent) { | 
| + fSrcRect = SkIRect::MakeEmpty(); | 
| + return; | 
| + } | 
| + if (alphaData.get() != NULL) { | 
| + addSMask(SkNEW_ARGS(SkPDFImage, | 
| + (alphaData.get(), bitmap, srcRect)))->unref(); | 
| + } | 
| + | 
| + initImageParams(false); | 
| +} | 
| + | 
| +SkPDFImage::SkPDFImage(SkStream* stream, const SkBitmap& bitmap, | 
| + const SkIRect& srcRect) | 
| + : fBitmap(bitmap), | 
| + fSrcRect(srcRect), | 
| + fEncoder(NULL) { | 
| + setData(stream); | 
| + insertInt("Length", getData()->getLength()); | 
| + setState(kNoCompression_State); | 
| + | 
| + initImageParams(true); | 
| +} | 
| + | 
| +SkPDFImage::SkPDFImage(SkPDFImage& pdfImage) | 
| + : SkPDFStream(pdfImage), | 
| + fBitmap(pdfImage.fBitmap), | 
| + fSrcRect(pdfImage.fSrcRect), | 
| + fEncoder(pdfImage.fEncoder){ | 
| + // Nothing to do here - the image params are already copied in SkPDFStream's | 
| 
vandebo (ex-Chrome)
2013/08/21 22:37:17
Remove comment.
 
ducky
2013/08/22 03:48:06
I think the comment about SkPDFStream is helpful -
 | 
| + // constructor, and the bitmap will be regenerated and re-encoded in | 
| + // populate. | 
| +} | 
| + | 
| +void SkPDFImage::initImageParams(bool isAlpha) { | 
| + SkBitmap::Config config = fBitmap.getConfig(); | 
| insertName("Type", "XObject"); | 
| insertName("Subtype", "Image"); | 
| - if (!doingAlpha && alphaOnly) { | 
| + bool alphaOnly = (config == SkBitmap::kA1_Config || | 
| + config == SkBitmap::kA8_Config); | 
| + | 
| + if (!isAlpha && alphaOnly) { | 
| // For alpha only images, we stretch a single pixel of black for | 
| // the color/shape part. | 
| SkAutoTUnref<SkPDFInt> one(new SkPDFInt(1)); | 
| insert("Width", one.get()); | 
| insert("Height", one.get()); | 
| } else { | 
| - insertInt("Width", srcRect.width()); | 
| - insertInt("Height", srcRect.height()); | 
| + insertInt("Width", fSrcRect.width()); | 
| + insertInt("Height", fSrcRect.height()); | 
| } | 
| - // if (!image mask) { | 
| - if (doingAlpha || alphaOnly) { | 
| + if (isAlpha || alphaOnly) { | 
| insertName("ColorSpace", "DeviceGray"); | 
| } else if (config == SkBitmap::kIndex8_Config) { | 
| - SkAutoLockPixels alp(bitmap); | 
| + SkAutoLockPixels alp(fBitmap); | 
| insert("ColorSpace", | 
| - makeIndexedColorSpace(bitmap.getColorTable()))->unref(); | 
| + makeIndexedColorSpace(fBitmap.getColorTable()))->unref(); | 
| } else { | 
| insertName("ColorSpace", "DeviceRGB"); | 
| } | 
| - // } | 
| int bitsPerComp = 8; | 
| if (config == SkBitmap::kARGB_4444_Config) { | 
| bitsPerComp = 4; | 
| - } else if (doingAlpha && config == SkBitmap::kA1_Config) { | 
| + } else if (isAlpha && config == SkBitmap::kA1_Config) { | 
| bitsPerComp = 1; | 
| } | 
| insertInt("BitsPerComponent", bitsPerComp); | 
| if (config == SkBitmap::kRGB_565_Config) { | 
| + SkASSERT(!isAlpha); | 
| SkAutoTUnref<SkPDFInt> zeroVal(new SkPDFInt(0)); | 
| SkAutoTUnref<SkPDFScalar> scale5Val( | 
| new SkPDFScalar(SkFloatToScalar(8.2258f))); // 255/2^5-1 | 
| @@ -337,3 +438,54 @@ SkPDFImage::SkPDFImage(SkStream* imageData, | 
| insert("Decode", decodeValue.get()); | 
| } | 
| } | 
| + | 
| +SkStream* SkPDFImage::getCompressedStream() { | 
| + SkDynamicMemoryWStream dctCompressedWStream; | 
| + if (fEncoder && fEncoder(&dctCompressedWStream, fBitmap, fSrcRect)) { | 
| 
vandebo (ex-Chrome)
2013/08/21 22:37:17
This doesn't handle the case where the image has a
 
ducky
2013/08/22 03:48:06
Yeah, this regressed a quite a few tests... fixed.
 | 
| + // Ensure compressed version is smaller than the uncompressed version | 
| + if (dctCompressedWStream.getOffset() < | 
| + get_uncompressed_size(fBitmap, fSrcRect)) { | 
| 
vandebo (ex-Chrome)
2013/08/21 22:37:17
if get_uncompressed_size is 1, you probably should
 
ducky
2013/08/22 03:48:06
Done.
 | 
| + SkData* data = dctCompressedWStream.copyToData(); | 
| + SkMemoryStream* stream = SkNEW_ARGS(SkMemoryStream, (data)); | 
| + data->unref(); | 
| + return stream; | 
| + } | 
| + } | 
| + return NULL; | 
| +} | 
| + | 
| +bool SkPDFImage::populate(SkPDFCatalog* catalog) { | 
| + if (getState() == kUnused_State) { | 
| + // Initializing image data for the first time. | 
| + if (!skip_compression(catalog)) { | 
| + SkAutoTUnref<SkStream> stream(getCompressedStream()); | 
| + if (stream.get() != NULL) { | 
| + setData(stream.get()); | 
| + insertName("Filter", "DCTDecode"); | 
| + insertInt("ColorTransform", kNoColorTransform); | 
| + insertInt("Length", getData()->getLength()); | 
| + setState(kCompressed_State); | 
| + } | 
| + } | 
| + | 
| + // Fallback if it doesn't work. | 
| + if (getState() == kUnused_State) { | 
| + SkAutoTUnref<SkStream> stream(extract_image_data(fBitmap, | 
| + fSrcRect)); | 
| + setData(stream.get()); | 
| + return INHERITED::populate(catalog); | 
| + } | 
| + } else if (getState() == kNoCompression_State && | 
| + !skip_compression(catalog) && | 
| + (SkFlate::HaveFlate() || fEncoder)) { | 
| + // Compression has not been requested when the stream was first created. | 
| + // But a new Catalog would want it compressed. | 
| 
vandebo (ex-Chrome)
2013/08/21 22:37:17
...created, but the new catalog wants it compresse
 
ducky
2013/08/22 03:48:06
Done.
 | 
| + if (!getSubstitute()) { | 
| + SkPDFStream* substitute = SkNEW_ARGS(SkPDFImage, (*this)); | 
| + setSubstitute(substitute); | 
| + catalog->setSubstitute(this, substitute); | 
| + } | 
| + return false; | 
| + } | 
| + return true; | 
| +} |