Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(41)

Side by Side Diff: src/images/SkDecodingImageGenerator.cpp

Issue 101973005: SkDecodingImageGenerator now uses SkStreamRewindable (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 "SkDecodingImageGenerator.h" 8 #include "SkDecodingImageGenerator.h"
9 #include "SkData.h" 9 #include "SkData.h"
10 #include "SkDiscardablePixelRef.h" 10 #include "SkDiscardablePixelRef.h"
11 #include "SkImageDecoder.h" 11 #include "SkImageDecoder.h"
12 #include "SkImagePriv.h"
13 #include "SkStream.h"
14
15
16 namespace {
17 /**
18 * Special allocator used by getPixels(). Uses preallocated memory
19 * provided.
20 */
21 class TargetAllocator : public SkBitmap::Allocator {
22 public:
23 TargetAllocator(void* target, size_t rowBytes, const SkImageInfo& info)
24 : fTarget(target)
25 , fRowBytes(rowBytes)
26 , fInfo(info) { }
27
28 virtual bool allocPixelRef(SkBitmap* bm, SkColorTable* ct) SK_OVERRIDE {
29 if ((SkImageInfoToBitmapConfig(fInfo) != bm->config())
30 || (bm->width() != fInfo.fWidth)
31 || (bm->height() != fInfo.fHeight)) {
32 return false;
33 }
34 bm->setConfig(bm->config(), bm->width(), bm->height(),
35 fRowBytes, bm->alphaType());
36 bm->setPixels(fTarget, ct);
37 return true;
38 }
39
40 private:
41 void* fTarget;
42 size_t fRowBytes;
43 SkImageInfo fInfo;
44 typedef SkBitmap::Allocator INHERITED;
45 };
46 } // namespace
47 ////////////////////////////////////////////////////////////////////////////////
12 48
13 SkDecodingImageGenerator::SkDecodingImageGenerator(SkData* data) 49 SkDecodingImageGenerator::SkDecodingImageGenerator(SkData* data)
14 : fData(data) { 50 : fData(data)
51 , fHasInfo(false)
52 , fDoCopyTo(false) {
15 SkASSERT(fData != NULL); 53 SkASSERT(fData != NULL);
54 fStream = SkNEW_ARGS(SkMemoryStream, (fData));
55 SkASSERT(fStream != NULL);
16 fData->ref(); 56 fData->ref();
17 } 57 }
18 58
59 SkDecodingImageGenerator::SkDecodingImageGenerator(SkStreamRewindable* stream)
60 : fData(NULL)
61 , fStream(stream)
62 , fHasInfo(false)
63 , fDoCopyTo(false) {
64 SkASSERT(fStream != NULL);
65 fHasInfo = false;
66 }
67
19 SkDecodingImageGenerator::~SkDecodingImageGenerator() { 68 SkDecodingImageGenerator::~SkDecodingImageGenerator() {
20 fData->unref(); 69 SkSafeUnref(fData);
70 fStream->unref();
21 } 71 }
22 72
23 SkData* SkDecodingImageGenerator::refEncodedData() { 73 SkData* SkDecodingImageGenerator::refEncodedData() {
24 // This functionality is used in `gm --serialize` 74 // This functionality is used in `gm --serialize`
25 fData->ref(); 75 if (fData != NULL) {
26 return fData; 76 return SkSafeRef(fData);
77 }
78 fData = fStream->getData();
79 if (fData != NULL) {
80 return SkSafeRef(fData);
81 }
82 return SkData::NewWithCopyFromStream(fStream);
27 } 83 }
28 84
29 bool SkDecodingImageGenerator::getInfo(SkImageInfo* info) { 85 bool SkDecodingImageGenerator::getInfo(SkImageInfo* info) {
30 SkASSERT(info != NULL); 86 // info can be NULL. If so, will update fInfo, fDoCopyTo, and fHasInfo.
31 return SkImageDecoder::DecodeMemoryToTarget(fData->data(), 87 if (fHasInfo) {
32 fData->size(), 88 if (info != NULL) {
33 info, NULL); 89 *info = fInfo;
90 }
91 return true;
92 }
93 SkAssertResult(fStream->rewind());
94 SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(fStream));
95 if (NULL == decoder.get()) {
96 return false;
97 }
98 SkBitmap bitmap;
99 if (!decoder->decode(fStream, &bitmap,
100 SkImageDecoder::kDecodeBounds_Mode)) {
101 return false;
102 }
103 if (bitmap.config() == SkBitmap::kNo_Config) {
104 return false;
105 }
106 if (!SkBitmapToImageInfo(bitmap, &fInfo)) {
scroggo 2013/12/05 21:07:18 Once https://codereview.chromium.org/68973005/ is
hal.canary 2013/12/05 22:29:29 That makes sense.
107 // We can't use bitmap.config() as is.
108 // Must be kARGB_4444_Config.
109 if (!bitmap.canCopyTo(SkBitmap::kARGB_8888_Config)) {
110 // kARGB_4444_Config can copy to kARGB_8888.
111 SkDEBUGFAIL("!bitmap->canCopyTo(SkBitmap::kARGB_8888_Config)");
112 return false;
113 }
114 fDoCopyTo = true;
115 fInfo.fWidth = bitmap.width();
116 fInfo.fHeight = bitmap.height();
117 fInfo.fColorType = kPMColor_SkColorType;
118 fInfo.fAlphaType = bitmap.alphaType();
119 }
120 if (info != NULL) {
121 *info = fInfo;
122 }
123 fHasInfo = true;
124 return true;
34 } 125 }
35 126
36 bool SkDecodingImageGenerator::getPixels(const SkImageInfo& info, 127 bool SkDecodingImageGenerator::getPixels(const SkImageInfo& info,
37 void* pixels, 128 void* pixels,
38 size_t rowBytes) { 129 size_t rowBytes) {
39 SkASSERT(pixels != NULL); 130 if (NULL == pixels) {
40 SkImageDecoder::Target target = {pixels, rowBytes}; 131 return false;
41 SkImageInfo tmpInfo = info; 132 }
42 return SkImageDecoder::DecodeMemoryToTarget(fData->data(), 133 if (!this->getInfo(NULL)) {
43 fData->size(), 134 return false;
44 &tmpInfo, &target); 135 }
136 SkAssertResult(fStream->rewind());
137 SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(fStream));
138 if (NULL == decoder.get()) {
139 return false;
140 }
141 if (fInfo != info) {
142 // if (SkImageInfoToBitmapConfig(info) == SkBitmap::kNo_Config) {
143 // return false;
144 // }
145 // The caller has specified a different info. for now, this
146 // is an error. In the future, we will check to see if we can
147 // convert.
148 return false;
149 }
150 int bpp = SkBitmap::ComputeBytesPerPixel(SkImageInfoToBitmapConfig(info));
151 if (static_cast<size_t>(bpp * info.fWidth) > rowBytes) {
152 return false;
153 }
154 SkBitmap bitmap;
155 if (!bitmap.setConfig(info, rowBytes)) {
156 return false;
157 }
158
159 TargetAllocator allocator(pixels, rowBytes, info);
160 if (!fDoCopyTo) {
161 decoder->setAllocator(&allocator);
162 }
163 bool success = decoder->decode(fStream, &bitmap,
164 SkImageDecoder::kDecodePixels_Mode);
165 decoder->setAllocator(NULL);
166 if (!success) {
167 return false;
168 }
169 if (fDoCopyTo) {
170 SkBitmap bm8888;
171 bitmap.copyTo(&bm8888, SkBitmap::kARGB_8888_Config, &allocator);
172 }
173 return true;
45 } 174 }
46 bool SkDecodingImageGenerator::Install(SkData* data, SkBitmap* dst, 175 bool SkDecodingImageGenerator::Install(SkData* data, SkBitmap* dst,
47 SkDiscardableMemory::Factory* factory) { 176 SkDiscardableMemory::Factory* factory) {
48 SkASSERT(data != NULL); 177 SkASSERT(data != NULL);
49 SkASSERT(dst != NULL); 178 SkASSERT(dst != NULL);
50 SkImageGenerator* gen(SkNEW_ARGS(SkDecodingImageGenerator, (data))); 179 SkImageGenerator* gen(SkNEW_ARGS(SkDecodingImageGenerator, (data)));
51 return SkDiscardablePixelRef::Install(gen, dst, factory); 180 return SkDiscardablePixelRef::Install(gen, dst, factory);
52 } 181 }
182
183 bool SkDecodingImageGenerator::Install(SkStreamRewindable* stream,
184 SkBitmap* dst,
185 SkDiscardableMemory::Factory* factory) {
186 SkASSERT(stream != NULL);
187 SkASSERT(dst != NULL);
188 SkImageGenerator* gen(SkNEW_ARGS(SkDecodingImageGenerator, (stream)));
189 return SkDiscardablePixelRef::Install(gen, dst, factory);
190 }
191
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698