| 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 namespace { | 17 namespace { | 
| 18 bool equal_modulo_alpha(const SkImageInfo& a, const SkImageInfo& b) { | 18 bool equal_modulo_alpha(const SkImageInfo& a, const SkImageInfo& b) { | 
| 19     return a.width() == b.width() && a.height() == b.height() && | 19     return a.width() == b.width() && a.height() == b.height() && | 
| 20            a.colorType() == b.colorType(); | 20            a.colorType() == b.colorType(); | 
| 21 } | 21 } | 
| 22 | 22 | 
| 23 class DecodingImageGenerator : public SkImageGenerator { | 23 class DecodingImageGenerator : public SkImageGenerator { | 
| 24 public: | 24 public: | 
| 25     virtual ~DecodingImageGenerator(); | 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 | 26 | 
| 33     SkData*                fData; | 27     SkData*                fData; | 
| 34     SkStreamRewindable*    fStream; | 28     SkStreamRewindable*    fStream; | 
| 35     const SkImageInfo      fInfo; | 29     const SkImageInfo      fInfo; | 
| 36     const int              fSampleSize; | 30     const int              fSampleSize; | 
| 37     const bool             fDitherImage; | 31     const bool             fDitherImage; | 
| 38 | 32 | 
| 39     DecodingImageGenerator(SkData* data, | 33     DecodingImageGenerator(SkData* data, | 
| 40                            SkStreamRewindable* stream, | 34                            SkStreamRewindable* stream, | 
| 41                            const SkImageInfo& info, | 35                            const SkImageInfo& info, | 
| 42                            int sampleSize, | 36                            int sampleSize, | 
| 43                            bool ditherImage); | 37                            bool ditherImage); | 
|  | 38 | 
|  | 39 protected: | 
|  | 40     virtual SkData* onRefEncodedData() SK_OVERRIDE; | 
|  | 41     virtual bool onGetInfo(SkImageInfo* info) SK_OVERRIDE { | 
|  | 42         *info = fInfo; | 
|  | 43         return true; | 
|  | 44     } | 
|  | 45     virtual bool onGetPixels(const SkImageInfo& info, | 
|  | 46                              void* pixels, size_t rowBytes, | 
|  | 47                              SkPMColor ctable[], int* ctableCount) SK_OVERRIDE; | 
|  | 48 | 
|  | 49 private: | 
| 44     typedef SkImageGenerator INHERITED; | 50     typedef SkImageGenerator INHERITED; | 
| 45 }; | 51 }; | 
| 46 | 52 | 
| 47 /** | 53 /** | 
| 48  *  Special allocator used by getPixels(). Uses preallocated memory | 54  *  Special allocator used by getPixels(). Uses preallocated memory | 
| 49  *  provided if possible, else fall-back on the default allocator | 55  *  provided if possible, else fall-back on the default allocator | 
| 50  */ | 56  */ | 
| 51 class TargetAllocator : public SkBitmap::Allocator { | 57 class TargetAllocator : public SkBitmap::Allocator { | 
| 52 public: | 58 public: | 
| 53     TargetAllocator(const SkImageInfo& info, | 59     TargetAllocator(const SkImageInfo& info, | 
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 116 { | 122 { | 
| 117     SkASSERT(stream != NULL); | 123     SkASSERT(stream != NULL); | 
| 118     SkSafeRef(fData);  // may be NULL. | 124     SkSafeRef(fData);  // may be NULL. | 
| 119 } | 125 } | 
| 120 | 126 | 
| 121 DecodingImageGenerator::~DecodingImageGenerator() { | 127 DecodingImageGenerator::~DecodingImageGenerator() { | 
| 122     SkSafeUnref(fData); | 128     SkSafeUnref(fData); | 
| 123     fStream->unref(); | 129     fStream->unref(); | 
| 124 } | 130 } | 
| 125 | 131 | 
| 126 bool DecodingImageGenerator::getInfo(SkImageInfo* info) { | 132 SkData* DecodingImageGenerator::onRefEncodedData() { | 
| 127     if (info != NULL) { |  | 
| 128         *info = fInfo; |  | 
| 129     } |  | 
| 130     return true; |  | 
| 131 } |  | 
| 132 |  | 
| 133 SkData* DecodingImageGenerator::refEncodedData() { |  | 
| 134     // This functionality is used in `gm --serialize` | 133     // This functionality is used in `gm --serialize` | 
| 135     // Does not encode options. | 134     // Does not encode options. | 
| 136     if (fData != NULL) { | 135     if (fData != NULL) { | 
| 137         return SkSafeRef(fData); | 136         return SkSafeRef(fData); | 
| 138     } | 137     } | 
| 139     // TODO(halcanary): SkStreamRewindable needs a refData() function | 138     // TODO(halcanary): SkStreamRewindable needs a refData() function | 
| 140     // which returns a cheap copy of the underlying data. | 139     // which returns a cheap copy of the underlying data. | 
| 141     if (!fStream->rewind()) { | 140     if (!fStream->rewind()) { | 
| 142         return NULL; | 141         return NULL; | 
| 143     } | 142     } | 
| 144     size_t length = fStream->getLength(); | 143     size_t length = fStream->getLength(); | 
| 145     if (0 == length) { | 144     if (0 == length) { | 
| 146         return NULL; | 145         return NULL; | 
| 147     } | 146     } | 
| 148     void* buffer = sk_malloc_flags(length, 0); | 147     void* buffer = sk_malloc_flags(length, 0); | 
| 149     SkCheckResult(fStream->read(buffer, length), length); | 148     SkCheckResult(fStream->read(buffer, length), length); | 
| 150     fData = SkData::NewFromMalloc(buffer, length); | 149     fData = SkData::NewFromMalloc(buffer, length); | 
| 151     return SkSafeRef(fData); | 150     return SkSafeRef(fData); | 
| 152 } | 151 } | 
| 153 | 152 | 
| 154 bool DecodingImageGenerator::getPixels(const SkImageInfo& info, | 153 bool DecodingImageGenerator::onGetPixels(const SkImageInfo& info, | 
| 155                                          void* pixels, | 154                                          void* pixels, size_t rowBytes, | 
| 156                                          size_t rowBytes) { | 155                                          SkPMColor ctableEntries[], int* ctableC
     ount) { | 
| 157     if (NULL == pixels) { |  | 
| 158         return false; |  | 
| 159     } |  | 
| 160     if (fInfo != info) { | 156     if (fInfo != info) { | 
| 161         // The caller has specified a different info.  This is an | 157         // The caller has specified a different info.  This is an | 
| 162         // error for this kind of SkImageGenerator.  Use the Options | 158         // error for this kind of SkImageGenerator.  Use the Options | 
| 163         // to change the settings. | 159         // to change the settings. | 
| 164         return false; | 160         return false; | 
| 165     } | 161     } | 
| 166     if (info.minRowBytes() > rowBytes) { |  | 
| 167         // The caller has specified a bad rowBytes. |  | 
| 168         return false; |  | 
| 169     } |  | 
| 170 | 162 | 
| 171     SkAssertResult(fStream->rewind()); | 163     SkAssertResult(fStream->rewind()); | 
| 172     SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(fStream)); | 164     SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(fStream)); | 
| 173     if (NULL == decoder.get()) { | 165     if (NULL == decoder.get()) { | 
| 174         return false; | 166         return false; | 
| 175     } | 167     } | 
| 176     decoder->setDitherImage(fDitherImage); | 168     decoder->setDitherImage(fDitherImage); | 
| 177     decoder->setSampleSize(fSampleSize); | 169     decoder->setSampleSize(fSampleSize); | 
| 178     decoder->setRequireUnpremultipliedColors( | 170     decoder->setRequireUnpremultipliedColors( | 
| 179             info.fAlphaType == kUnpremul_SkAlphaType); | 171             info.fAlphaType == kUnpremul_SkAlphaType); | 
| (...skipping 15 matching lines...) Expand all  Loading... | 
| 195         bool copySuccess = bitmap.copyTo(&bm, info.colorType(), &allocator); | 187         bool copySuccess = bitmap.copyTo(&bm, info.colorType(), &allocator); | 
| 196         if (!copySuccess || allocator.isReady()) { | 188         if (!copySuccess || allocator.isReady()) { | 
| 197             SkDEBUGFAIL("bitmap.copyTo(requestedConfig) failed."); | 189             SkDEBUGFAIL("bitmap.copyTo(requestedConfig) failed."); | 
| 198             // Earlier we checked canCopyto(); we expect consistency. | 190             // Earlier we checked canCopyto(); we expect consistency. | 
| 199             return false; | 191             return false; | 
| 200         } | 192         } | 
| 201         SkASSERT(check_alpha(info.alphaType(), bm.alphaType())); | 193         SkASSERT(check_alpha(info.alphaType(), bm.alphaType())); | 
| 202     } else { | 194     } else { | 
| 203         SkASSERT(check_alpha(info.alphaType(), bitmap.alphaType())); | 195         SkASSERT(check_alpha(info.alphaType(), bitmap.alphaType())); | 
| 204     } | 196     } | 
|  | 197 | 
|  | 198     if (kIndex_8_SkColorType == info.colorType()) { | 
|  | 199         if (kIndex_8_SkColorType != bitmap.colorType()) { | 
|  | 200             return false;   // they asked for Index8, but we didn't receive that
      from decoder | 
|  | 201         } | 
|  | 202         SkColorTable* ctable = bitmap.getColorTable(); | 
|  | 203         if (NULL == ctable) { | 
|  | 204             return false; | 
|  | 205         } | 
|  | 206         const int count = ctable->count(); | 
|  | 207         memcpy(ctableEntries, ctable->lockColors(), count * sizeof(SkPMColor)); | 
|  | 208         ctable->unlockColors(); | 
|  | 209         *ctableCount = count; | 
|  | 210     } | 
| 205     return true; | 211     return true; | 
| 206 } | 212 } | 
| 207 | 213 | 
| 208 // A contructor-type function that returns NULL on failure.  This | 214 // A contructor-type function that returns NULL on failure.  This | 
| 209 // prevents the returned SkImageGenerator from ever being in a bad | 215 // prevents the returned SkImageGenerator from ever being in a bad | 
| 210 // state.  Called by both Create() functions | 216 // state.  Called by both Create() functions | 
| 211 SkImageGenerator* CreateDecodingImageGenerator( | 217 SkImageGenerator* CreateDecodingImageGenerator( | 
| 212         SkData* data, | 218         SkData* data, | 
| 213         SkStreamRewindable* stream, | 219         SkStreamRewindable* stream, | 
| 214         const SkDecodingImageGenerator::Options& opts) { | 220         const SkDecodingImageGenerator::Options& opts) { | 
| 215     SkASSERT(stream); | 221     SkASSERT(stream); | 
| 216     SkAutoTUnref<SkStreamRewindable> autoStream(stream);  // always unref this. | 222     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     SkAssertResult(autoStream->rewind()); | 
| 223     SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(autoStream)); | 224     SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(autoStream)); | 
| 224     if (NULL == decoder.get()) { | 225     if (NULL == decoder.get()) { | 
| 225         return NULL; | 226         return NULL; | 
| 226     } | 227     } | 
| 227     SkBitmap bitmap; | 228     SkBitmap bitmap; | 
| 228     decoder->setSampleSize(opts.fSampleSize); | 229     decoder->setSampleSize(opts.fSampleSize); | 
| 229     decoder->setRequireUnpremultipliedColors(opts.fRequireUnpremul); | 230     decoder->setRequireUnpremultipliedColors(opts.fRequireUnpremul); | 
| 230     if (!decoder->decode(stream, &bitmap, | 231     if (!decoder->decode(stream, &bitmap, SkImageDecoder::kDecodeBounds_Mode)) { | 
| 231                          SkImageDecoder::kDecodeBounds_Mode)) { |  | 
| 232         return NULL; | 232         return NULL; | 
| 233     } | 233     } | 
| 234     if (bitmap.config() == SkBitmap::kNo_Config) { | 234     if (kUnknown_SkColorType == bitmap.colorType()) { | 
| 235         return NULL; | 235         return NULL; | 
| 236     } | 236     } | 
| 237 | 237 | 
| 238     SkImageInfo info = bitmap.info(); | 238     SkImageInfo info = bitmap.info(); | 
| 239 | 239 | 
| 240     if (!opts.fUseRequestedColorType) { | 240     if (opts.fUseRequestedColorType && (opts.fRequestedColorType != info.colorTy
     pe())) { | 
| 241         // Use default |  | 
| 242         if (kIndex_8_SkColorType == bitmap.colorType()) { |  | 
| 243             // We don't support kIndex8 because we don't support |  | 
| 244             // colortables in this workflow. |  | 
| 245             info.fColorType = kN32_SkColorType; |  | 
| 246         } |  | 
| 247     } else { |  | 
| 248         if (!bitmap.canCopyTo(opts.fRequestedColorType)) { | 241         if (!bitmap.canCopyTo(opts.fRequestedColorType)) { | 
| 249             SkASSERT(bitmap.colorType() != opts.fRequestedColorType); | 242             SkASSERT(bitmap.colorType() != opts.fRequestedColorType); | 
| 250             return NULL;  // Can not translate to needed config. | 243             return NULL;  // Can not translate to needed config. | 
| 251         } | 244         } | 
| 252         info.fColorType = opts.fRequestedColorType; | 245         info.fColorType = opts.fRequestedColorType; | 
| 253     } | 246     } | 
| 254 | 247 | 
| 255     if (opts.fRequireUnpremul && info.fAlphaType != kOpaque_SkAlphaType) { | 248     if (opts.fRequireUnpremul && info.fAlphaType != kOpaque_SkAlphaType) { | 
| 256         info.fAlphaType = kUnpremul_SkAlphaType; | 249         info.fAlphaType = kUnpremul_SkAlphaType; | 
| 257     } | 250     } | 
| (...skipping 23 matching lines...) Expand all  Loading... | 
| 281         SkStreamRewindable* stream, | 274         SkStreamRewindable* stream, | 
| 282         const SkDecodingImageGenerator::Options& opts) { | 275         const SkDecodingImageGenerator::Options& opts) { | 
| 283     SkASSERT(stream != NULL); | 276     SkASSERT(stream != NULL); | 
| 284     SkASSERT(stream->unique()); | 277     SkASSERT(stream->unique()); | 
| 285     if ((stream == NULL) || !stream->unique()) { | 278     if ((stream == NULL) || !stream->unique()) { | 
| 286         SkSafeUnref(stream); | 279         SkSafeUnref(stream); | 
| 287         return NULL; | 280         return NULL; | 
| 288     } | 281     } | 
| 289     return CreateDecodingImageGenerator(NULL, stream, opts); | 282     return CreateDecodingImageGenerator(NULL, stream, opts); | 
| 290 } | 283 } | 
| OLD | NEW | 
|---|