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.

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

mercurial