gfx/skia/trunk/src/images/SkImageDecoder.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 2006 The Android Open Source Project
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
michael@0 9 #include "SkImageDecoder.h"
michael@0 10 #include "SkBitmap.h"
michael@0 11 #include "SkImagePriv.h"
michael@0 12 #include "SkPixelRef.h"
michael@0 13 #include "SkStream.h"
michael@0 14 #include "SkTemplates.h"
michael@0 15 #include "SkCanvas.h"
michael@0 16
michael@0 17 static SkBitmap::Config gDeviceConfig = SkBitmap::kNo_Config;
michael@0 18
michael@0 19 SkBitmap::Config SkImageDecoder::GetDeviceConfig()
michael@0 20 {
michael@0 21 return gDeviceConfig;
michael@0 22 }
michael@0 23
michael@0 24 void SkImageDecoder::SetDeviceConfig(SkBitmap::Config config)
michael@0 25 {
michael@0 26 gDeviceConfig = config;
michael@0 27 }
michael@0 28
michael@0 29 ///////////////////////////////////////////////////////////////////////////////
michael@0 30
michael@0 31 SkImageDecoder::SkImageDecoder()
michael@0 32 : fPeeker(NULL)
michael@0 33 , fChooser(NULL)
michael@0 34 , fAllocator(NULL)
michael@0 35 , fSampleSize(1)
michael@0 36 , fDefaultPref(SkBitmap::kNo_Config)
michael@0 37 , fDitherImage(true)
michael@0 38 , fUsePrefTable(false)
michael@0 39 , fSkipWritingZeroes(false)
michael@0 40 , fPreferQualityOverSpeed(false)
michael@0 41 , fRequireUnpremultipliedColors(false) {
michael@0 42 }
michael@0 43
michael@0 44 SkImageDecoder::~SkImageDecoder() {
michael@0 45 SkSafeUnref(fPeeker);
michael@0 46 SkSafeUnref(fChooser);
michael@0 47 SkSafeUnref(fAllocator);
michael@0 48 }
michael@0 49
michael@0 50 void SkImageDecoder::copyFieldsToOther(SkImageDecoder* other) {
michael@0 51 if (NULL == other) {
michael@0 52 return;
michael@0 53 }
michael@0 54 other->setPeeker(fPeeker);
michael@0 55 other->setChooser(fChooser);
michael@0 56 other->setAllocator(fAllocator);
michael@0 57 other->setSampleSize(fSampleSize);
michael@0 58 if (fUsePrefTable) {
michael@0 59 other->setPrefConfigTable(fPrefTable);
michael@0 60 } else {
michael@0 61 other->fDefaultPref = fDefaultPref;
michael@0 62 }
michael@0 63 other->setDitherImage(fDitherImage);
michael@0 64 other->setSkipWritingZeroes(fSkipWritingZeroes);
michael@0 65 other->setPreferQualityOverSpeed(fPreferQualityOverSpeed);
michael@0 66 other->setRequireUnpremultipliedColors(fRequireUnpremultipliedColors);
michael@0 67 }
michael@0 68
michael@0 69 SkImageDecoder::Format SkImageDecoder::getFormat() const {
michael@0 70 return kUnknown_Format;
michael@0 71 }
michael@0 72
michael@0 73 const char* SkImageDecoder::getFormatName() const {
michael@0 74 return GetFormatName(this->getFormat());
michael@0 75 }
michael@0 76
michael@0 77 const char* SkImageDecoder::GetFormatName(Format format) {
michael@0 78 switch (format) {
michael@0 79 case kUnknown_Format:
michael@0 80 return "Unknown Format";
michael@0 81 case kBMP_Format:
michael@0 82 return "BMP";
michael@0 83 case kGIF_Format:
michael@0 84 return "GIF";
michael@0 85 case kICO_Format:
michael@0 86 return "ICO";
michael@0 87 case kJPEG_Format:
michael@0 88 return "JPEG";
michael@0 89 case kPNG_Format:
michael@0 90 return "PNG";
michael@0 91 case kWBMP_Format:
michael@0 92 return "WBMP";
michael@0 93 case kWEBP_Format:
michael@0 94 return "WEBP";
michael@0 95 default:
michael@0 96 SkDEBUGFAIL("Invalid format type!");
michael@0 97 }
michael@0 98 return "Unknown Format";
michael@0 99 }
michael@0 100
michael@0 101 SkImageDecoder::Peeker* SkImageDecoder::setPeeker(Peeker* peeker) {
michael@0 102 SkRefCnt_SafeAssign(fPeeker, peeker);
michael@0 103 return peeker;
michael@0 104 }
michael@0 105
michael@0 106 SkImageDecoder::Chooser* SkImageDecoder::setChooser(Chooser* chooser) {
michael@0 107 SkRefCnt_SafeAssign(fChooser, chooser);
michael@0 108 return chooser;
michael@0 109 }
michael@0 110
michael@0 111 SkBitmap::Allocator* SkImageDecoder::setAllocator(SkBitmap::Allocator* alloc) {
michael@0 112 SkRefCnt_SafeAssign(fAllocator, alloc);
michael@0 113 return alloc;
michael@0 114 }
michael@0 115
michael@0 116 void SkImageDecoder::setSampleSize(int size) {
michael@0 117 if (size < 1) {
michael@0 118 size = 1;
michael@0 119 }
michael@0 120 fSampleSize = size;
michael@0 121 }
michael@0 122
michael@0 123 bool SkImageDecoder::chooseFromOneChoice(SkBitmap::Config config, int width,
michael@0 124 int height) const {
michael@0 125 Chooser* chooser = fChooser;
michael@0 126
michael@0 127 if (NULL == chooser) { // no chooser, we just say YES to decoding :)
michael@0 128 return true;
michael@0 129 }
michael@0 130 chooser->begin(1);
michael@0 131 chooser->inspect(0, config, width, height);
michael@0 132 return chooser->choose() == 0;
michael@0 133 }
michael@0 134
michael@0 135 bool SkImageDecoder::allocPixelRef(SkBitmap* bitmap,
michael@0 136 SkColorTable* ctable) const {
michael@0 137 return bitmap->allocPixels(fAllocator, ctable);
michael@0 138 }
michael@0 139
michael@0 140 ///////////////////////////////////////////////////////////////////////////////
michael@0 141
michael@0 142 void SkImageDecoder::setPrefConfigTable(const PrefConfigTable& prefTable) {
michael@0 143 fUsePrefTable = true;
michael@0 144 fPrefTable = prefTable;
michael@0 145 }
michael@0 146
michael@0 147 SkBitmap::Config SkImageDecoder::getPrefConfig(SrcDepth srcDepth,
michael@0 148 bool srcHasAlpha) const {
michael@0 149 SkBitmap::Config config = SkBitmap::kNo_Config;
michael@0 150
michael@0 151 if (fUsePrefTable) {
michael@0 152 switch (srcDepth) {
michael@0 153 case kIndex_SrcDepth:
michael@0 154 config = srcHasAlpha ? fPrefTable.fPrefFor_8Index_YesAlpha_src
michael@0 155 : fPrefTable.fPrefFor_8Index_NoAlpha_src;
michael@0 156 break;
michael@0 157 case k8BitGray_SrcDepth:
michael@0 158 config = fPrefTable.fPrefFor_8Gray_src;
michael@0 159 break;
michael@0 160 case k32Bit_SrcDepth:
michael@0 161 config = srcHasAlpha ? fPrefTable.fPrefFor_8bpc_YesAlpha_src
michael@0 162 : fPrefTable.fPrefFor_8bpc_NoAlpha_src;
michael@0 163 break;
michael@0 164 }
michael@0 165 } else {
michael@0 166 config = fDefaultPref;
michael@0 167 }
michael@0 168
michael@0 169 if (SkBitmap::kNo_Config == config) {
michael@0 170 config = SkImageDecoder::GetDeviceConfig();
michael@0 171 }
michael@0 172 return config;
michael@0 173 }
michael@0 174
michael@0 175 bool SkImageDecoder::decode(SkStream* stream, SkBitmap* bm,
michael@0 176 SkBitmap::Config pref, Mode mode) {
michael@0 177 // we reset this to false before calling onDecode
michael@0 178 fShouldCancelDecode = false;
michael@0 179 // assign this, for use by getPrefConfig(), in case fUsePrefTable is false
michael@0 180 fDefaultPref = pref;
michael@0 181
michael@0 182 // pass a temporary bitmap, so that if we return false, we are assured of
michael@0 183 // leaving the caller's bitmap untouched.
michael@0 184 SkBitmap tmp;
michael@0 185 if (!this->onDecode(stream, &tmp, mode)) {
michael@0 186 return false;
michael@0 187 }
michael@0 188 bm->swap(tmp);
michael@0 189 return true;
michael@0 190 }
michael@0 191
michael@0 192 bool SkImageDecoder::decodeSubset(SkBitmap* bm, const SkIRect& rect,
michael@0 193 SkBitmap::Config pref) {
michael@0 194 // we reset this to false before calling onDecodeSubset
michael@0 195 fShouldCancelDecode = false;
michael@0 196 // assign this, for use by getPrefConfig(), in case fUsePrefTable is false
michael@0 197 fDefaultPref = pref;
michael@0 198
michael@0 199 return this->onDecodeSubset(bm, rect);
michael@0 200 }
michael@0 201
michael@0 202 bool SkImageDecoder::buildTileIndex(SkStreamRewindable* stream,
michael@0 203 int *width, int *height) {
michael@0 204 // we reset this to false before calling onBuildTileIndex
michael@0 205 fShouldCancelDecode = false;
michael@0 206
michael@0 207 return this->onBuildTileIndex(stream, width, height);
michael@0 208 }
michael@0 209
michael@0 210 bool SkImageDecoder::cropBitmap(SkBitmap *dst, SkBitmap *src, int sampleSize,
michael@0 211 int dstX, int dstY, int width, int height,
michael@0 212 int srcX, int srcY) {
michael@0 213 int w = width / sampleSize;
michael@0 214 int h = height / sampleSize;
michael@0 215 if (src->config() == SkBitmap::kIndex8_Config) {
michael@0 216 // kIndex8 does not allow drawing via an SkCanvas, as is done below.
michael@0 217 // Instead, use extractSubset. Note that this shares the SkPixelRef and
michael@0 218 // SkColorTable.
michael@0 219 // FIXME: Since src is discarded in practice, this holds on to more
michael@0 220 // pixels than is strictly necessary. Switch to a copy if memory
michael@0 221 // savings are more important than speed here. This also means
michael@0 222 // that the pixels in dst can not be reused (though there is no
michael@0 223 // allocation, which was already done on src).
michael@0 224 int x = (dstX - srcX) / sampleSize;
michael@0 225 int y = (dstY - srcY) / sampleSize;
michael@0 226 SkIRect subset = SkIRect::MakeXYWH(x, y, w, h);
michael@0 227 return src->extractSubset(dst, subset);
michael@0 228 }
michael@0 229 // if the destination has no pixels then we must allocate them.
michael@0 230 if (dst->isNull()) {
michael@0 231 dst->setConfig(src->config(), w, h, 0, src->alphaType());
michael@0 232
michael@0 233 if (!this->allocPixelRef(dst, NULL)) {
michael@0 234 SkDEBUGF(("failed to allocate pixels needed to crop the bitmap"));
michael@0 235 return false;
michael@0 236 }
michael@0 237 }
michael@0 238 // check to see if the destination is large enough to decode the desired
michael@0 239 // region. If this assert fails we will just draw as much of the source
michael@0 240 // into the destination that we can.
michael@0 241 if (dst->width() < w || dst->height() < h) {
michael@0 242 SkDEBUGF(("SkImageDecoder::cropBitmap does not have a large enough bitmap.\n"));
michael@0 243 }
michael@0 244
michael@0 245 // Set the Src_Mode for the paint to prevent transparency issue in the
michael@0 246 // dest in the event that the dest was being re-used.
michael@0 247 SkPaint paint;
michael@0 248 paint.setXfermodeMode(SkXfermode::kSrc_Mode);
michael@0 249
michael@0 250 SkCanvas canvas(*dst);
michael@0 251 canvas.drawSprite(*src, (srcX - dstX) / sampleSize,
michael@0 252 (srcY - dstY) / sampleSize,
michael@0 253 &paint);
michael@0 254 return true;
michael@0 255 }
michael@0 256
michael@0 257 ///////////////////////////////////////////////////////////////////////////////
michael@0 258
michael@0 259 bool SkImageDecoder::DecodeFile(const char file[], SkBitmap* bm,
michael@0 260 SkBitmap::Config pref, Mode mode, Format* format) {
michael@0 261 SkASSERT(file);
michael@0 262 SkASSERT(bm);
michael@0 263
michael@0 264 SkAutoTUnref<SkStreamRewindable> stream(SkStream::NewFromFile(file));
michael@0 265 if (stream.get()) {
michael@0 266 if (SkImageDecoder::DecodeStream(stream, bm, pref, mode, format)) {
michael@0 267 bm->pixelRef()->setURI(file);
michael@0 268 return true;
michael@0 269 }
michael@0 270 }
michael@0 271 return false;
michael@0 272 }
michael@0 273
michael@0 274 bool SkImageDecoder::DecodeMemory(const void* buffer, size_t size, SkBitmap* bm,
michael@0 275 SkBitmap::Config pref, Mode mode, Format* format) {
michael@0 276 if (0 == size) {
michael@0 277 return false;
michael@0 278 }
michael@0 279 SkASSERT(buffer);
michael@0 280
michael@0 281 SkMemoryStream stream(buffer, size);
michael@0 282 return SkImageDecoder::DecodeStream(&stream, bm, pref, mode, format);
michael@0 283 }
michael@0 284
michael@0 285 bool SkImageDecoder::DecodeStream(SkStreamRewindable* stream, SkBitmap* bm,
michael@0 286 SkBitmap::Config pref, Mode mode,
michael@0 287 Format* format) {
michael@0 288 SkASSERT(stream);
michael@0 289 SkASSERT(bm);
michael@0 290
michael@0 291 bool success = false;
michael@0 292 SkImageDecoder* codec = SkImageDecoder::Factory(stream);
michael@0 293
michael@0 294 if (NULL != codec) {
michael@0 295 success = codec->decode(stream, bm, pref, mode);
michael@0 296 if (success && format) {
michael@0 297 *format = codec->getFormat();
michael@0 298 if (kUnknown_Format == *format) {
michael@0 299 if (stream->rewind()) {
michael@0 300 *format = GetStreamFormat(stream);
michael@0 301 }
michael@0 302 }
michael@0 303 }
michael@0 304 delete codec;
michael@0 305 }
michael@0 306 return success;
michael@0 307 }

mercurial