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

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: rebased again 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
« no previous file with comments | « src/images/SkDecodingImageGenerator.h ('k') | src/images/SkImageDecoder.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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);
56 SkASSERT(fStream->unique());
16 fData->ref(); 57 fData->ref();
17 } 58 }
18 59
60 SkDecodingImageGenerator::SkDecodingImageGenerator(SkStreamRewindable* stream)
61 : fData(NULL)
62 , fStream(stream)
63 , fHasInfo(false)
64 , fDoCopyTo(false) {
65 SkASSERT(fStream != NULL);
66 SkASSERT(fStream->unique());
67 }
68
19 SkDecodingImageGenerator::~SkDecodingImageGenerator() { 69 SkDecodingImageGenerator::~SkDecodingImageGenerator() {
20 fData->unref(); 70 SkSafeUnref(fData);
71 fStream->unref();
21 } 72 }
22 73
74 // TODO(halcanary): Give this macro a better name and move it into SkTypes.h
75 #ifdef SK_DEBUG
76 #define SkCheckResult(expr, value) SkASSERT((value) == (expr))
77 #else
78 #define SkCheckResult(expr, value) (void)(expr)
79 #endif
80
23 SkData* SkDecodingImageGenerator::refEncodedData() { 81 SkData* SkDecodingImageGenerator::refEncodedData() {
24 // This functionality is used in `gm --serialize` 82 // This functionality is used in `gm --serialize`
25 fData->ref(); 83 if (fData != NULL) {
26 return fData; 84 return SkSafeRef(fData);
85 }
86 // TODO(halcanary): SkStreamRewindable needs a refData() function
87 // which returns a cheap copy of the underlying data.
88 if (!fStream->rewind()) {
89 return NULL;
90 }
91 size_t length = fStream->getLength();
92 if (0 == length) {
93 return NULL;
94 }
95 void* buffer = sk_malloc_flags(length, 0);
96 SkCheckResult(fStream->read(buffer, length), length);
97 fData = SkData::NewFromMalloc(buffer, length);
98 return SkSafeRef(fData);
27 } 99 }
28 100
29 bool SkDecodingImageGenerator::getInfo(SkImageInfo* info) { 101 bool SkDecodingImageGenerator::getInfo(SkImageInfo* info) {
30 SkASSERT(info != NULL); 102 // info can be NULL. If so, will update fInfo, fDoCopyTo, and fHasInfo.
31 return SkImageDecoder::DecodeMemoryToTarget(fData->data(), 103 if (fHasInfo) {
32 fData->size(), 104 if (info != NULL) {
33 info, NULL); 105 *info = fInfo;
106 }
107 return true;
108 }
109 SkAssertResult(fStream->rewind());
110 SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(fStream));
111 if (NULL == decoder.get()) {
112 return false;
113 }
114 SkBitmap bitmap;
115 if (!decoder->decode(fStream, &bitmap,
116 SkImageDecoder::kDecodeBounds_Mode)) {
117 return false;
118 }
119 if (bitmap.config() == SkBitmap::kNo_Config) {
120 return false;
121 }
122 if (!SkBitmapToImageInfo(bitmap, &fInfo)) {
123 // We can't use bitmap.config() as is.
124 // Must be kARGB_4444_Config.
125 if (!bitmap.canCopyTo(SkBitmap::kARGB_8888_Config)) {
126 // kARGB_4444_Config can copy to kARGB_8888.
127 SkDEBUGFAIL("!bitmap->canCopyTo(SkBitmap::kARGB_8888_Config)");
128 return false;
129 }
130 fDoCopyTo = true;
131 fInfo.fWidth = bitmap.width();
132 fInfo.fHeight = bitmap.height();
133 fInfo.fColorType = kPMColor_SkColorType;
134 fInfo.fAlphaType = bitmap.alphaType();
135 }
136 if (info != NULL) {
137 *info = fInfo;
138 }
139 fHasInfo = true;
140 return true;
34 } 141 }
35 142
36 bool SkDecodingImageGenerator::getPixels(const SkImageInfo& info, 143 bool SkDecodingImageGenerator::getPixels(const SkImageInfo& info,
37 void* pixels, 144 void* pixels,
38 size_t rowBytes) { 145 size_t rowBytes) {
39 SkASSERT(pixels != NULL); 146 if (NULL == pixels) {
40 SkImageDecoder::Target target = {pixels, rowBytes}; 147 return false;
41 SkImageInfo tmpInfo = info; 148 }
42 return SkImageDecoder::DecodeMemoryToTarget(fData->data(), 149 if (!this->getInfo(NULL)) {
43 fData->size(), 150 return false;
44 &tmpInfo, &target); 151 }
152 if (SkImageInfoToBitmapConfig(info) == SkBitmap::kNo_Config) {
153 return false; // Unsupported SkColorType.
154 }
155 SkAssertResult(fStream->rewind());
156 SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(fStream));
157 if (NULL == decoder.get()) {
158 return false;
159 }
160 if (fInfo != info) {
161 // The caller has specified a different info. For now, this
162 // is an error. In the future, we will check to see if we can
163 // convert.
164 return false;
165 }
166 int bpp = SkBitmap::ComputeBytesPerPixel(SkImageInfoToBitmapConfig(info));
167 if (static_cast<size_t>(bpp * info.fWidth) > rowBytes) {
168 return false;
169 }
170 SkBitmap bitmap;
171 if (!bitmap.setConfig(info, rowBytes)) {
172 return false;
173 }
174
175 TargetAllocator allocator(pixels, rowBytes, info);
176 if (!fDoCopyTo) {
177 decoder->setAllocator(&allocator);
178 }
179 bool success = decoder->decode(fStream, &bitmap,
180 SkImageDecoder::kDecodePixels_Mode);
181 decoder->setAllocator(NULL);
182 if (!success) {
183 return false;
184 }
185 if (fDoCopyTo) {
186 SkBitmap bm8888;
187 bitmap.copyTo(&bm8888, SkBitmap::kARGB_8888_Config, &allocator);
188 }
189 return true;
45 } 190 }
46 bool SkDecodingImageGenerator::Install(SkData* data, SkBitmap* dst, 191 bool SkDecodingImageGenerator::Install(SkData* data, SkBitmap* dst,
47 SkDiscardableMemory::Factory* factory) { 192 SkDiscardableMemory::Factory* factory) {
48 SkASSERT(data != NULL); 193 SkASSERT(data != NULL);
49 SkASSERT(dst != NULL); 194 SkASSERT(dst != NULL);
50 SkImageGenerator* gen(SkNEW_ARGS(SkDecodingImageGenerator, (data))); 195 SkImageGenerator* gen(SkNEW_ARGS(SkDecodingImageGenerator, (data)));
51 return SkDiscardablePixelRef::Install(gen, dst, factory); 196 return SkDiscardablePixelRef::Install(gen, dst, factory);
52 } 197 }
198
199 bool SkDecodingImageGenerator::Install(SkStreamRewindable* stream,
200 SkBitmap* dst,
201 SkDiscardableMemory::Factory* factory) {
202 SkASSERT(stream != NULL);
203 SkASSERT(dst != NULL);
204 if ((stream == NULL) || !stream->unique()) {
205 SkSafeUnref(stream);
206 return false;
207 }
208 SkImageGenerator* gen(SkNEW_ARGS(SkDecodingImageGenerator, (stream)));
209 return SkDiscardablePixelRef::Install(gen, dst, factory);
210 }
211
OLDNEW
« no previous file with comments | « src/images/SkDecodingImageGenerator.h ('k') | src/images/SkImageDecoder.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698