gfx/skia/trunk/src/images/SkDecodingImageGenerator.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 /*
michael@0 2 * Copyright 2013 Google Inc.
michael@0 3 *
michael@0 4 * Use of this source code is governed by a BSD-style license that can be
michael@0 5 * found in the LICENSE file.
michael@0 6 */
michael@0 7
michael@0 8 #include "SkData.h"
michael@0 9 #include "SkDecodingImageGenerator.h"
michael@0 10 #include "SkImageDecoder.h"
michael@0 11 #include "SkImageInfo.h"
michael@0 12 #include "SkImageGenerator.h"
michael@0 13 #include "SkImagePriv.h"
michael@0 14 #include "SkStream.h"
michael@0 15 #include "SkUtils.h"
michael@0 16
michael@0 17 static bool equal_modulo_alpha(const SkImageInfo& a, const SkImageInfo& b) {
michael@0 18 return a.width() == b.width() && a.height() == b.height() &&
michael@0 19 a.colorType() == b.colorType();
michael@0 20 }
michael@0 21
michael@0 22 namespace {
michael@0 23 /**
michael@0 24 * Special allocator used by getPixels(). Uses preallocated memory
michael@0 25 * provided if possible, else fall-back on the default allocator
michael@0 26 */
michael@0 27 class TargetAllocator : public SkBitmap::Allocator {
michael@0 28 public:
michael@0 29 TargetAllocator(const SkImageInfo& info,
michael@0 30 void* target,
michael@0 31 size_t rowBytes)
michael@0 32 : fInfo(info)
michael@0 33 , fTarget(target)
michael@0 34 , fRowBytes(rowBytes)
michael@0 35 {}
michael@0 36
michael@0 37 bool isReady() { return (fTarget != NULL); }
michael@0 38
michael@0 39 virtual bool allocPixelRef(SkBitmap* bm, SkColorTable* ct) {
michael@0 40 if (NULL == fTarget || !equal_modulo_alpha(fInfo, bm->info())) {
michael@0 41 // Call default allocator.
michael@0 42 return bm->allocPixels(NULL, ct);
michael@0 43 }
michael@0 44
michael@0 45 // TODO(halcanary): verify that all callers of this function
michael@0 46 // will respect new RowBytes. Will be moot once rowbytes belongs
michael@0 47 // to PixelRef.
michael@0 48 bm->installPixels(fInfo, fTarget, fRowBytes, NULL, NULL);
michael@0 49
michael@0 50 fTarget = NULL; // never alloc same pixels twice!
michael@0 51 return true;
michael@0 52 }
michael@0 53
michael@0 54 private:
michael@0 55 const SkImageInfo fInfo;
michael@0 56 void* fTarget; // Block of memory to be supplied as pixel memory
michael@0 57 // in allocPixelRef. Must be large enough to hold
michael@0 58 // a bitmap described by fInfo and fRowBytes
michael@0 59 const size_t fRowBytes; // rowbytes for the destination bitmap
michael@0 60
michael@0 61 typedef SkBitmap::Allocator INHERITED;
michael@0 62 };
michael@0 63
michael@0 64 // TODO(halcanary): Give this macro a better name and move it into SkTypes.h
michael@0 65 #ifdef SK_DEBUG
michael@0 66 #define SkCheckResult(expr, value) SkASSERT((value) == (expr))
michael@0 67 #else
michael@0 68 #define SkCheckResult(expr, value) (void)(expr)
michael@0 69 #endif
michael@0 70
michael@0 71 #ifdef SK_DEBUG
michael@0 72 inline bool check_alpha(SkAlphaType reported, SkAlphaType actual) {
michael@0 73 return ((reported == actual)
michael@0 74 || ((reported == kPremul_SkAlphaType)
michael@0 75 && (actual == kOpaque_SkAlphaType)));
michael@0 76 }
michael@0 77 #endif // SK_DEBUG
michael@0 78
michael@0 79 } // namespace
michael@0 80 ////////////////////////////////////////////////////////////////////////////////
michael@0 81
michael@0 82 SkDecodingImageGenerator::SkDecodingImageGenerator(
michael@0 83 SkData* data,
michael@0 84 SkStreamRewindable* stream,
michael@0 85 const SkImageInfo& info,
michael@0 86 int sampleSize,
michael@0 87 bool ditherImage)
michael@0 88 : fData(data)
michael@0 89 , fStream(stream)
michael@0 90 , fInfo(info)
michael@0 91 , fSampleSize(sampleSize)
michael@0 92 , fDitherImage(ditherImage)
michael@0 93 {
michael@0 94 SkASSERT(stream != NULL);
michael@0 95 SkSafeRef(fData); // may be NULL.
michael@0 96 }
michael@0 97
michael@0 98 SkDecodingImageGenerator::~SkDecodingImageGenerator() {
michael@0 99 SkSafeUnref(fData);
michael@0 100 fStream->unref();
michael@0 101 }
michael@0 102
michael@0 103 bool SkDecodingImageGenerator::getInfo(SkImageInfo* info) {
michael@0 104 if (info != NULL) {
michael@0 105 *info = fInfo;
michael@0 106 }
michael@0 107 return true;
michael@0 108 }
michael@0 109
michael@0 110 SkData* SkDecodingImageGenerator::refEncodedData() {
michael@0 111 // This functionality is used in `gm --serialize`
michael@0 112 // Does not encode options.
michael@0 113 if (fData != NULL) {
michael@0 114 return SkSafeRef(fData);
michael@0 115 }
michael@0 116 // TODO(halcanary): SkStreamRewindable needs a refData() function
michael@0 117 // which returns a cheap copy of the underlying data.
michael@0 118 if (!fStream->rewind()) {
michael@0 119 return NULL;
michael@0 120 }
michael@0 121 size_t length = fStream->getLength();
michael@0 122 if (0 == length) {
michael@0 123 return NULL;
michael@0 124 }
michael@0 125 void* buffer = sk_malloc_flags(length, 0);
michael@0 126 SkCheckResult(fStream->read(buffer, length), length);
michael@0 127 fData = SkData::NewFromMalloc(buffer, length);
michael@0 128 return SkSafeRef(fData);
michael@0 129 }
michael@0 130
michael@0 131 bool SkDecodingImageGenerator::getPixels(const SkImageInfo& info,
michael@0 132 void* pixels,
michael@0 133 size_t rowBytes) {
michael@0 134 if (NULL == pixels) {
michael@0 135 return false;
michael@0 136 }
michael@0 137 if (fInfo != info) {
michael@0 138 // The caller has specified a different info. This is an
michael@0 139 // error for this kind of SkImageGenerator. Use the Options
michael@0 140 // to change the settings.
michael@0 141 return false;
michael@0 142 }
michael@0 143 if (info.minRowBytes() > rowBytes) {
michael@0 144 // The caller has specified a bad rowBytes.
michael@0 145 return false;
michael@0 146 }
michael@0 147
michael@0 148 SkAssertResult(fStream->rewind());
michael@0 149 SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(fStream));
michael@0 150 if (NULL == decoder.get()) {
michael@0 151 return false;
michael@0 152 }
michael@0 153 decoder->setDitherImage(fDitherImage);
michael@0 154 decoder->setSampleSize(fSampleSize);
michael@0 155
michael@0 156 SkBitmap bitmap;
michael@0 157 TargetAllocator allocator(fInfo, pixels, rowBytes);
michael@0 158 decoder->setAllocator(&allocator);
michael@0 159 // TODO: need to be able to pass colortype directly to decoder
michael@0 160 SkBitmap::Config legacyConfig = SkColorTypeToBitmapConfig(info.colorType());
michael@0 161 bool success = decoder->decode(fStream, &bitmap, legacyConfig,
michael@0 162 SkImageDecoder::kDecodePixels_Mode);
michael@0 163 decoder->setAllocator(NULL);
michael@0 164 if (!success) {
michael@0 165 return false;
michael@0 166 }
michael@0 167 if (allocator.isReady()) { // Did not use pixels!
michael@0 168 SkBitmap bm;
michael@0 169 SkASSERT(bitmap.canCopyTo(info.colorType()));
michael@0 170 bool copySuccess = bitmap.copyTo(&bm, info.colorType(), &allocator);
michael@0 171 if (!copySuccess || allocator.isReady()) {
michael@0 172 SkDEBUGFAIL("bitmap.copyTo(requestedConfig) failed.");
michael@0 173 // Earlier we checked canCopyto(); we expect consistency.
michael@0 174 return false;
michael@0 175 }
michael@0 176 SkASSERT(check_alpha(info.alphaType(), bm.alphaType()));
michael@0 177 } else {
michael@0 178 SkASSERT(check_alpha(info.alphaType(), bitmap.alphaType()));
michael@0 179 }
michael@0 180 return true;
michael@0 181 }
michael@0 182
michael@0 183 SkImageGenerator* SkDecodingImageGenerator::Create(
michael@0 184 SkData* data,
michael@0 185 const SkDecodingImageGenerator::Options& opts) {
michael@0 186 SkASSERT(data != NULL);
michael@0 187 if (NULL == data) {
michael@0 188 return NULL;
michael@0 189 }
michael@0 190 SkStreamRewindable* stream = SkNEW_ARGS(SkMemoryStream, (data));
michael@0 191 SkASSERT(stream != NULL);
michael@0 192 SkASSERT(stream->unique());
michael@0 193 return SkDecodingImageGenerator::Create(data, stream, opts);
michael@0 194 }
michael@0 195
michael@0 196 SkImageGenerator* SkDecodingImageGenerator::Create(
michael@0 197 SkStreamRewindable* stream,
michael@0 198 const SkDecodingImageGenerator::Options& opts) {
michael@0 199 SkASSERT(stream != NULL);
michael@0 200 SkASSERT(stream->unique());
michael@0 201 if ((stream == NULL) || !stream->unique()) {
michael@0 202 SkSafeUnref(stream);
michael@0 203 return NULL;
michael@0 204 }
michael@0 205 return SkDecodingImageGenerator::Create(NULL, stream, opts);
michael@0 206 }
michael@0 207
michael@0 208 // A contructor-type function that returns NULL on failure. This
michael@0 209 // prevents the returned SkImageGenerator from ever being in a bad
michael@0 210 // state. Called by both Create() functions
michael@0 211 SkImageGenerator* SkDecodingImageGenerator::Create(
michael@0 212 SkData* data,
michael@0 213 SkStreamRewindable* stream,
michael@0 214 const SkDecodingImageGenerator::Options& opts) {
michael@0 215 SkASSERT(stream);
michael@0 216 SkAutoTUnref<SkStreamRewindable> autoStream(stream); // always unref this.
michael@0 217 if (opts.fUseRequestedColorType &&
michael@0 218 (kIndex_8_SkColorType == opts.fRequestedColorType)) {
michael@0 219 // We do not support indexed color with SkImageGenerators,
michael@0 220 return NULL;
michael@0 221 }
michael@0 222 SkAssertResult(autoStream->rewind());
michael@0 223 SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(autoStream));
michael@0 224 if (NULL == decoder.get()) {
michael@0 225 return NULL;
michael@0 226 }
michael@0 227 SkBitmap bitmap;
michael@0 228 decoder->setSampleSize(opts.fSampleSize);
michael@0 229 if (!decoder->decode(stream, &bitmap,
michael@0 230 SkImageDecoder::kDecodeBounds_Mode)) {
michael@0 231 return NULL;
michael@0 232 }
michael@0 233 if (bitmap.config() == SkBitmap::kNo_Config) {
michael@0 234 return NULL;
michael@0 235 }
michael@0 236
michael@0 237 SkImageInfo info = bitmap.info();
michael@0 238
michael@0 239 if (!opts.fUseRequestedColorType) {
michael@0 240 // Use default
michael@0 241 if (kIndex_8_SkColorType == bitmap.colorType()) {
michael@0 242 // We don't support kIndex8 because we don't support
michael@0 243 // colortables in this workflow.
michael@0 244 info.fColorType = kPMColor_SkColorType;
michael@0 245 }
michael@0 246 } else {
michael@0 247 if (!bitmap.canCopyTo(opts.fRequestedColorType)) {
michael@0 248 SkASSERT(bitmap.colorType() != opts.fRequestedColorType);
michael@0 249 return NULL; // Can not translate to needed config.
michael@0 250 }
michael@0 251 info.fColorType = opts.fRequestedColorType;
michael@0 252 }
michael@0 253 return SkNEW_ARGS(SkDecodingImageGenerator,
michael@0 254 (data, autoStream.detach(), info,
michael@0 255 opts.fSampleSize, opts.fDitherImage));
michael@0 256 }

mercurial