| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkData.h" | 8 #include "SkData.h" |
| 9 #include "SkDecodingImageGenerator.h" | 9 #include "SkDecodingImageGenerator.h" |
| 10 #include "SkImageDecoder.h" | 10 #include "SkImageDecoder.h" |
| 11 #include "SkImageInfo.h" | 11 #include "SkImageInfo.h" |
| 12 #include "SkImageGenerator.h" | 12 #include "SkImageGenerator.h" |
| 13 #include "SkImagePriv.h" | 13 #include "SkImagePriv.h" |
| 14 #include "SkStream.h" | 14 #include "SkStream.h" |
| 15 #include "SkUtils.h" | 15 #include "SkUtils.h" |
| 16 | 16 |
| 17 static bool equal_modulo_alpha(const SkImageInfo& a, const SkImageInfo& b) { | 17 namespace { |
| 18 bool equal_modulo_alpha(const SkImageInfo& a, const SkImageInfo& b) { |
| 18 return a.width() == b.width() && a.height() == b.height() && | 19 return a.width() == b.width() && a.height() == b.height() && |
| 19 a.colorType() == b.colorType(); | 20 a.colorType() == b.colorType(); |
| 20 } | 21 } |
| 21 | 22 |
| 22 namespace { | 23 class DecodingImageGenerator : public SkImageGenerator { |
| 24 public: |
| 25 virtual ~DecodingImageGenerator(); |
| 26 virtual SkData* refEncodedData() SK_OVERRIDE; |
| 27 // This implementaion of getInfo() always returns true. |
| 28 virtual bool getInfo(SkImageInfo* info) SK_OVERRIDE; |
| 29 virtual bool getPixels(const SkImageInfo& info, |
| 30 void* pixels, |
| 31 size_t rowBytes) SK_OVERRIDE; |
| 32 |
| 33 SkData* fData; |
| 34 SkStreamRewindable* fStream; |
| 35 const SkImageInfo fInfo; |
| 36 const int fSampleSize; |
| 37 const bool fDitherImage; |
| 38 |
| 39 DecodingImageGenerator(SkData* data, |
| 40 SkStreamRewindable* stream, |
| 41 const SkImageInfo& info, |
| 42 int sampleSize, |
| 43 bool ditherImage); |
| 44 typedef SkImageGenerator INHERITED; |
| 45 }; |
| 46 |
| 23 /** | 47 /** |
| 24 * Special allocator used by getPixels(). Uses preallocated memory | 48 * Special allocator used by getPixels(). Uses preallocated memory |
| 25 * provided if possible, else fall-back on the default allocator | 49 * provided if possible, else fall-back on the default allocator |
| 26 */ | 50 */ |
| 27 class TargetAllocator : public SkBitmap::Allocator { | 51 class TargetAllocator : public SkBitmap::Allocator { |
| 28 public: | 52 public: |
| 29 TargetAllocator(const SkImageInfo& info, | 53 TargetAllocator(const SkImageInfo& info, |
| 30 void* target, | 54 void* target, |
| 31 size_t rowBytes) | 55 size_t rowBytes) |
| 32 : fInfo(info) | 56 : fInfo(info) |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 69 #endif | 93 #endif |
| 70 | 94 |
| 71 #ifdef SK_DEBUG | 95 #ifdef SK_DEBUG |
| 72 inline bool check_alpha(SkAlphaType reported, SkAlphaType actual) { | 96 inline bool check_alpha(SkAlphaType reported, SkAlphaType actual) { |
| 73 return ((reported == actual) | 97 return ((reported == actual) |
| 74 || ((reported == kPremul_SkAlphaType) | 98 || ((reported == kPremul_SkAlphaType) |
| 75 && (actual == kOpaque_SkAlphaType))); | 99 && (actual == kOpaque_SkAlphaType))); |
| 76 } | 100 } |
| 77 #endif // SK_DEBUG | 101 #endif // SK_DEBUG |
| 78 | 102 |
| 79 } // namespace | |
| 80 //////////////////////////////////////////////////////////////////////////////// | 103 //////////////////////////////////////////////////////////////////////////////// |
| 81 | 104 |
| 82 SkDecodingImageGenerator::SkDecodingImageGenerator( | 105 DecodingImageGenerator::DecodingImageGenerator( |
| 83 SkData* data, | 106 SkData* data, |
| 84 SkStreamRewindable* stream, | 107 SkStreamRewindable* stream, |
| 85 const SkImageInfo& info, | 108 const SkImageInfo& info, |
| 86 int sampleSize, | 109 int sampleSize, |
| 87 bool ditherImage) | 110 bool ditherImage) |
| 88 : fData(data) | 111 : fData(data) |
| 89 , fStream(stream) | 112 , fStream(stream) |
| 90 , fInfo(info) | 113 , fInfo(info) |
| 91 , fSampleSize(sampleSize) | 114 , fSampleSize(sampleSize) |
| 92 , fDitherImage(ditherImage) | 115 , fDitherImage(ditherImage) |
| 93 { | 116 { |
| 94 SkASSERT(stream != NULL); | 117 SkASSERT(stream != NULL); |
| 95 SkSafeRef(fData); // may be NULL. | 118 SkSafeRef(fData); // may be NULL. |
| 96 } | 119 } |
| 97 | 120 |
| 98 SkDecodingImageGenerator::~SkDecodingImageGenerator() { | 121 DecodingImageGenerator::~DecodingImageGenerator() { |
| 99 SkSafeUnref(fData); | 122 SkSafeUnref(fData); |
| 100 fStream->unref(); | 123 fStream->unref(); |
| 101 } | 124 } |
| 102 | 125 |
| 103 bool SkDecodingImageGenerator::getInfo(SkImageInfo* info) { | 126 bool DecodingImageGenerator::getInfo(SkImageInfo* info) { |
| 104 if (info != NULL) { | 127 if (info != NULL) { |
| 105 *info = fInfo; | 128 *info = fInfo; |
| 106 } | 129 } |
| 107 return true; | 130 return true; |
| 108 } | 131 } |
| 109 | 132 |
| 110 SkData* SkDecodingImageGenerator::refEncodedData() { | 133 SkData* DecodingImageGenerator::refEncodedData() { |
| 111 // This functionality is used in `gm --serialize` | 134 // This functionality is used in `gm --serialize` |
| 112 // Does not encode options. | 135 // Does not encode options. |
| 113 if (fData != NULL) { | 136 if (fData != NULL) { |
| 114 return SkSafeRef(fData); | 137 return SkSafeRef(fData); |
| 115 } | 138 } |
| 116 // TODO(halcanary): SkStreamRewindable needs a refData() function | 139 // TODO(halcanary): SkStreamRewindable needs a refData() function |
| 117 // which returns a cheap copy of the underlying data. | 140 // which returns a cheap copy of the underlying data. |
| 118 if (!fStream->rewind()) { | 141 if (!fStream->rewind()) { |
| 119 return NULL; | 142 return NULL; |
| 120 } | 143 } |
| 121 size_t length = fStream->getLength(); | 144 size_t length = fStream->getLength(); |
| 122 if (0 == length) { | 145 if (0 == length) { |
| 123 return NULL; | 146 return NULL; |
| 124 } | 147 } |
| 125 void* buffer = sk_malloc_flags(length, 0); | 148 void* buffer = sk_malloc_flags(length, 0); |
| 126 SkCheckResult(fStream->read(buffer, length), length); | 149 SkCheckResult(fStream->read(buffer, length), length); |
| 127 fData = SkData::NewFromMalloc(buffer, length); | 150 fData = SkData::NewFromMalloc(buffer, length); |
| 128 return SkSafeRef(fData); | 151 return SkSafeRef(fData); |
| 129 } | 152 } |
| 130 | 153 |
| 131 bool SkDecodingImageGenerator::getPixels(const SkImageInfo& info, | 154 bool DecodingImageGenerator::getPixels(const SkImageInfo& info, |
| 132 void* pixels, | 155 void* pixels, |
| 133 size_t rowBytes) { | 156 size_t rowBytes) { |
| 134 if (NULL == pixels) { | 157 if (NULL == pixels) { |
| 135 return false; | 158 return false; |
| 136 } | 159 } |
| 137 if (fInfo != info) { | 160 if (fInfo != info) { |
| 138 // The caller has specified a different info. This is an | 161 // The caller has specified a different info. This is an |
| 139 // error for this kind of SkImageGenerator. Use the Options | 162 // error for this kind of SkImageGenerator. Use the Options |
| 140 // to change the settings. | 163 // to change the settings. |
| 141 return false; | 164 return false; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 173 // Earlier we checked canCopyto(); we expect consistency. | 196 // Earlier we checked canCopyto(); we expect consistency. |
| 174 return false; | 197 return false; |
| 175 } | 198 } |
| 176 SkASSERT(check_alpha(info.alphaType(), bm.alphaType())); | 199 SkASSERT(check_alpha(info.alphaType(), bm.alphaType())); |
| 177 } else { | 200 } else { |
| 178 SkASSERT(check_alpha(info.alphaType(), bitmap.alphaType())); | 201 SkASSERT(check_alpha(info.alphaType(), bitmap.alphaType())); |
| 179 } | 202 } |
| 180 return true; | 203 return true; |
| 181 } | 204 } |
| 182 | 205 |
| 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 } | |
| 195 | |
| 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 } | |
| 207 | |
| 208 // A contructor-type function that returns NULL on failure. This | 206 // A contructor-type function that returns NULL on failure. This |
| 209 // prevents the returned SkImageGenerator from ever being in a bad | 207 // prevents the returned SkImageGenerator from ever being in a bad |
| 210 // state. Called by both Create() functions | 208 // state. Called by both Create() functions |
| 211 SkImageGenerator* SkDecodingImageGenerator::Create( | 209 SkImageGenerator* CreateDecodingImageGenerator( |
| 212 SkData* data, | 210 SkData* data, |
| 213 SkStreamRewindable* stream, | 211 SkStreamRewindable* stream, |
| 214 const SkDecodingImageGenerator::Options& opts) { | 212 const SkDecodingImageGenerator::Options& opts) { |
| 215 SkASSERT(stream); | 213 SkASSERT(stream); |
| 216 SkAutoTUnref<SkStreamRewindable> autoStream(stream); // always unref this. | 214 SkAutoTUnref<SkStreamRewindable> autoStream(stream); // always unref this. |
| 217 if (opts.fUseRequestedColorType && | 215 if (opts.fUseRequestedColorType && |
| 218 (kIndex_8_SkColorType == opts.fRequestedColorType)) { | 216 (kIndex_8_SkColorType == opts.fRequestedColorType)) { |
| 219 // We do not support indexed color with SkImageGenerators, | 217 // We do not support indexed color with SkImageGenerators, |
| 220 return NULL; | 218 return NULL; |
| 221 } | 219 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 243 // colortables in this workflow. | 241 // colortables in this workflow. |
| 244 info.fColorType = kPMColor_SkColorType; | 242 info.fColorType = kPMColor_SkColorType; |
| 245 } | 243 } |
| 246 } else { | 244 } else { |
| 247 if (!bitmap.canCopyTo(opts.fRequestedColorType)) { | 245 if (!bitmap.canCopyTo(opts.fRequestedColorType)) { |
| 248 SkASSERT(bitmap.colorType() != opts.fRequestedColorType); | 246 SkASSERT(bitmap.colorType() != opts.fRequestedColorType); |
| 249 return NULL; // Can not translate to needed config. | 247 return NULL; // Can not translate to needed config. |
| 250 } | 248 } |
| 251 info.fColorType = opts.fRequestedColorType; | 249 info.fColorType = opts.fRequestedColorType; |
| 252 } | 250 } |
| 253 return SkNEW_ARGS(SkDecodingImageGenerator, | 251 return SkNEW_ARGS(DecodingImageGenerator, |
| 254 (data, autoStream.detach(), info, | 252 (data, autoStream.detach(), info, |
| 255 opts.fSampleSize, opts.fDitherImage)); | 253 opts.fSampleSize, opts.fDitherImage)); |
| 256 } | 254 } |
| 255 |
| 256 } // namespace |
| 257 |
| 258 //////////////////////////////////////////////////////////////////////////////// |
| 259 |
| 260 SkImageGenerator* SkDecodingImageGenerator::Create( |
| 261 SkData* data, |
| 262 const SkDecodingImageGenerator::Options& opts) { |
| 263 SkASSERT(data != NULL); |
| 264 if (NULL == data) { |
| 265 return NULL; |
| 266 } |
| 267 SkStreamRewindable* stream = SkNEW_ARGS(SkMemoryStream, (data)); |
| 268 SkASSERT(stream != NULL); |
| 269 SkASSERT(stream->unique()); |
| 270 return CreateDecodingImageGenerator(data, stream, opts); |
| 271 } |
| 272 |
| 273 SkImageGenerator* SkDecodingImageGenerator::Create( |
| 274 SkStreamRewindable* stream, |
| 275 const SkDecodingImageGenerator::Options& opts) { |
| 276 SkASSERT(stream != NULL); |
| 277 SkASSERT(stream->unique()); |
| 278 if ((stream == NULL) || !stream->unique()) { |
| 279 SkSafeUnref(stream); |
| 280 return NULL; |
| 281 } |
| 282 return CreateDecodingImageGenerator(NULL, stream, opts); |
| 283 } |
| OLD | NEW |