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

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

Issue 1828433004: Revert of Delete SkImageDecoder (Closed) Base URL: https://skia.googlesource.com/skia.git@fix-animator
Patch Set: Created 4 years, 9 months 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
« no previous file with comments | « src/images/SkImageDecoder_ktx.cpp ('k') | src/images/SkImageDecoder_libgif.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1
2 /*
3 * Copyright 2007 The Android Open Source Project
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9
10 #include "bmpdecoderhelper.h"
11 #include "SkColorPriv.h"
12 #include "SkData.h"
13 #include "SkImageDecoder.h"
14 #include "SkScaledBitmapSampler.h"
15 #include "SkStream.h"
16 #include "SkStreamPriv.h"
17 #include "SkTDArray.h"
18
19 class SkBMPImageDecoder : public SkImageDecoder {
20 public:
21 SkBMPImageDecoder() {}
22
23 Format getFormat() const override {
24 return kBMP_Format;
25 }
26
27 protected:
28 Result onDecode(SkStream* stream, SkBitmap* bm, Mode mode) override;
29
30 private:
31 typedef SkImageDecoder INHERITED;
32 };
33
34 ///////////////////////////////////////////////////////////////////////////////
35 DEFINE_DECODER_CREATOR(BMPImageDecoder);
36 ///////////////////////////////////////////////////////////////////////////////
37
38 static bool is_bmp(SkStreamRewindable* stream) {
39 static const char kBmpMagic[] = { 'B', 'M' };
40
41
42 char buffer[sizeof(kBmpMagic)];
43
44 return stream->read(buffer, sizeof(kBmpMagic)) == sizeof(kBmpMagic) &&
45 !memcmp(buffer, kBmpMagic, sizeof(kBmpMagic));
46 }
47
48 static SkImageDecoder* sk_libbmp_dfactory(SkStreamRewindable* stream) {
49 if (is_bmp(stream)) {
50 return new SkBMPImageDecoder;
51 }
52 return nullptr;
53 }
54
55 static SkImageDecoder_DecodeReg gReg(sk_libbmp_dfactory);
56
57 static SkImageDecoder::Format get_format_bmp(SkStreamRewindable* stream) {
58 if (is_bmp(stream)) {
59 return SkImageDecoder::kBMP_Format;
60 }
61 return SkImageDecoder::kUnknown_Format;
62 }
63
64 static SkImageDecoder_FormatReg gFormatReg(get_format_bmp);
65
66 ///////////////////////////////////////////////////////////////////////////////
67
68 class SkBmpDecoderCallback : public image_codec::BmpDecoderCallback {
69 public:
70 // we don't copy the bitmap, just remember the pointer
71 SkBmpDecoderCallback(bool justBounds) : fJustBounds(justBounds) {}
72
73 // override from BmpDecoderCallback
74 virtual uint8* SetSize(int width, int height) {
75 fWidth = width;
76 fHeight = height;
77 if (fJustBounds) {
78 return nullptr;
79 }
80
81 fRGB.setCount(width * height * 3); // 3 == r, g, b
82 return fRGB.begin();
83 }
84
85 int width() const { return fWidth; }
86 int height() const { return fHeight; }
87 const uint8_t* rgb() const { return fRGB.begin(); }
88
89 private:
90 SkTDArray<uint8_t> fRGB;
91 int fWidth;
92 int fHeight;
93 bool fJustBounds;
94 };
95
96 SkImageDecoder::Result SkBMPImageDecoder::onDecode(SkStream* stream, SkBitmap* b m, Mode mode) {
97 // First read the entire stream, so that all of the data can be passed to
98 // the BmpDecoderHelper.
99
100 auto data = SkCopyStreamToData(stream);
101 if (!data) {
102 return kFailure;
103 }
104
105 // Byte length of all of the data.
106 const size_t length = data->size();
107 if (0 == length) {
108 return kFailure;
109 }
110
111 const bool justBounds = SkImageDecoder::kDecodeBounds_Mode == mode;
112 SkBmpDecoderCallback callback(justBounds);
113
114 // Now decode the BMP into callback's rgb() array [r,g,b, r,g,b, ...]
115 {
116 image_codec::BmpDecoderHelper helper;
117 const int max_pixels = 16383*16383; // max width*height
118 if (!helper.DecodeImage((const char*) data->data(), length,
119 max_pixels, &callback)) {
120 return kFailure;
121 }
122 }
123
124 // we don't need this anymore, so free it now (before we try to allocate
125 // the bitmap's pixels) rather than waiting for its destructor
126 data.reset(nullptr);
127
128 int width = callback.width();
129 int height = callback.height();
130 SkColorType colorType = this->getPrefColorType(k32Bit_SrcDepth, false);
131
132 // only accept prefConfig if it makes sense for us
133 if (kARGB_4444_SkColorType != colorType && kRGB_565_SkColorType != colorType ) {
134 colorType = kN32_SkColorType;
135 }
136
137 SkScaledBitmapSampler sampler(width, height, getSampleSize());
138
139 bm->setInfo(SkImageInfo::Make(sampler.scaledWidth(), sampler.scaledHeight(),
140 colorType, kOpaque_SkAlphaType));
141
142 if (justBounds) {
143 return kSuccess;
144 }
145
146 if (!this->allocPixelRef(bm, nullptr)) {
147 return kFailure;
148 }
149
150 SkAutoLockPixels alp(*bm);
151
152 if (!sampler.begin(bm, SkScaledBitmapSampler::kRGB, *this)) {
153 return kFailure;
154 }
155
156 const int srcRowBytes = width * 3;
157 const int dstHeight = sampler.scaledHeight();
158 const uint8_t* srcRow = callback.rgb();
159
160 srcRow += sampler.srcY0() * srcRowBytes;
161 for (int y = 0; y < dstHeight; y++) {
162 sampler.next(srcRow);
163 srcRow += sampler.srcDY() * srcRowBytes;
164 }
165 return kSuccess;
166 }
OLDNEW
« no previous file with comments | « src/images/SkImageDecoder_ktx.cpp ('k') | src/images/SkImageDecoder_libgif.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698