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

Side by Side Diff: src/codec/SkScaledCodec.cpp

Issue 1413363008: Rename SkScaledCodec.cpp to SkSampledCodec.cpp (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years, 1 month 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/codec/SkSampledCodec.cpp ('k') | no next file » | 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 * Copyright 2015 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include "SkCodec.h"
9 #include "SkCodecPriv.h"
10 #include "SkSampledCodec.h"
11
12 // FIXME: Rename this file to SkSampledCodec.cpp
13
14 SkSampledCodec::SkSampledCodec(SkCodec* codec)
15 : INHERITED(codec->getInfo())
16 , fCodec(codec)
17 {}
18
19 SkISize SkSampledCodec::onGetSampledDimensions(int sampleSize) const {
20 // Fast path for when we are not scaling.
21 if (1 == sampleSize) {
22 return fCodec->getInfo().dimensions();
23 }
24
25 const int width = fCodec->getInfo().width();
26 const int height = fCodec->getInfo().height();
27
28 // Check if the codec can provide the scaling natively.
29 float scale = get_scale_from_sample_size(sampleSize);
30 SkSize idealSize = SkSize::Make(scale * (float) width, scale * (float) heigh t);
31 SkISize nativeSize = fCodec->getScaledDimensions(scale);
32 float widthDiff = SkTAbs(((float) nativeSize.width()) - idealSize.width());
33 float heightDiff = SkTAbs(((float) nativeSize.height()) - idealSize.height() );
34 // Native scaling is preferred to sampling. If we can scale natively to
35 // within one of the ideal value, we should choose to scale natively.
36 if (widthDiff < 1.0f && heightDiff < 1.0f) {
37 return nativeSize;
38 }
39
40 // Provide the scaling by sampling.
41 return SkISize::Make(get_scaled_dimension(width, sampleSize),
42 get_scaled_dimension(height, sampleSize));
43 }
44
45 SkCodec::Result SkSampledCodec::onGetAndroidPixels(const SkImageInfo& info, void * pixels,
46 size_t rowBytes, AndroidOptions& options) {
47 // Create an Options struct for the codec.
48 SkCodec::Options codecOptions;
49 codecOptions.fZeroInitialized = options.fZeroInitialized;
50
51 SkIRect* subset = options.fSubset;
52 if (!subset || subset->size() == fCodec->getInfo().dimensions()) {
53 if (fCodec->dimensionsSupported(info.dimensions())) {
54 return fCodec->getPixels(info, pixels, rowBytes, &codecOptions, opti ons.fColorPtr,
55 options.fColorCount);
56 }
57
58 // If the native codec does not support the requested scale, scale by sa mpling.
59 return this->sampledDecode(info, pixels, rowBytes, options);
60 }
61
62 // We are performing a subset decode.
63 int sampleSize = options.fSampleSize;
64 SkISize scaledSize = this->onGetSampledDimensions(sampleSize);
65 if (!fCodec->dimensionsSupported(scaledSize)) {
66 // If the native codec does not support the requested scale, scale by sa mpling.
67 return this->sampledDecode(info, pixels, rowBytes, options);
68 }
69
70 // Calculate the scaled subset bounds.
71 int scaledSubsetX = subset->x() / sampleSize;
72 int scaledSubsetY = subset->y() / sampleSize;
73 int scaledSubsetWidth = info.width();
74 int scaledSubsetHeight = info.height();
75
76 // Start the scanline decode.
77 SkIRect scanlineSubset = SkIRect::MakeXYWH(scaledSubsetX, 0, scaledSubsetWid th,
78 scaledSize.height());
79 codecOptions.fSubset = &scanlineSubset;
80 SkCodec::Result result = fCodec->startScanlineDecode(info.makeWH(scaledSize. width(),
81 scaledSize.height()), &codecOptions, options.fColorPtr, options.fCol orCount);
82 if (SkCodec::kSuccess != result) {
83 return result;
84 }
85
86 // At this point, we are only concerned with subsetting. Either no scale wa s
87 // requested, or the fCodec is handling the scale.
88 switch (fCodec->getScanlineOrder()) {
89 case SkCodec::kTopDown_SkScanlineOrder:
90 case SkCodec::kNone_SkScanlineOrder: {
91 if (!fCodec->skipScanlines(scaledSubsetY)) {
92 fCodec->fillIncompleteImage(info, pixels, rowBytes, options.fZer oInitialized,
93 scaledSubsetHeight, 0);
94 return SkCodec::kIncompleteInput;
95 }
96
97 int decodedLines = fCodec->getScanlines(pixels, scaledSubsetHeight, rowBytes);
98 if (decodedLines != scaledSubsetHeight) {
99 return SkCodec::kIncompleteInput;
100 }
101 return SkCodec::kSuccess;
102 }
103 default:
104 SkASSERT(false);
105 return SkCodec::kUnimplemented;
106 }
107 }
108
109
110 SkCodec::Result SkSampledCodec::sampledDecode(const SkImageInfo& info, void* pix els,
111 size_t rowBytes, AndroidOptions& options) {
112 // Create options struct for the codec.
113 SkCodec::Options sampledOptions;
114 sampledOptions.fZeroInitialized = options.fZeroInitialized;
115
116 // Check if there is a subset.
117 SkIRect subset;
118 int subsetY = 0;
119 int subsetWidth = fCodec->getInfo().width();
120 int subsetHeight = fCodec->getInfo().height();
121 if (options.fSubset) {
122 // We will need to know about subsetting in the y-dimension in order to use the
123 // scanline decoder.
124 SkIRect* subsetPtr = options.fSubset;
125 subsetY = subsetPtr->y();
126 subsetWidth = subsetPtr->width();
127 subsetHeight = subsetPtr->height();
128
129 // The scanline decoder only needs to be aware of subsetting in the x-di mension.
130 subset.setXYWH(subsetPtr->x(), 0, subsetWidth, fCodec->getInfo().height( ));
131 sampledOptions.fSubset = &subset;
132 }
133
134 // Start the scanline decode.
135 SkCodec::Result result = fCodec->startScanlineDecode(
136 info.makeWH(fCodec->getInfo().width(), fCodec->getInfo().height()), &sampledOptions,
137 options.fColorPtr, options.fColorCount);
138 if (SkCodec::kSuccess != result) {
139 return result;
140 }
141
142 SkSampler* sampler = fCodec->getSampler(true);
143 if (!sampler) {
144 return SkCodec::kUnimplemented;
145 }
146
147 // Since we guarantee that output dimensions are always at least one (even i f the sampleSize
148 // is greater than a given dimension), the input sampleSize is not always th e sampleSize that
149 // we use in practice.
150 const int sampleX = subsetWidth / info.width();
151 const int sampleY = subsetHeight / info.height();
152 if (sampler->setSampleX(sampleX) != info.width()) {
153 return SkCodec::kInvalidScale;
154 }
155 if (get_scaled_dimension(subsetHeight, sampleY) != info.height()) {
156 return SkCodec::kInvalidScale;
157 }
158
159 const int samplingOffsetY = get_start_coord(sampleY);
160 const int startY = samplingOffsetY + subsetY;
161 int dstHeight = info.height();
162 switch(fCodec->getScanlineOrder()) {
163 case SkCodec::kTopDown_SkScanlineOrder: {
164 if (!fCodec->skipScanlines(startY)) {
165 fCodec->fillIncompleteImage(info, pixels, rowBytes, options.fZer oInitialized,
166 dstHeight, 0);
167 return SkCodec::kIncompleteInput;
168 }
169 void* pixelPtr = pixels;
170 for (int y = 0; y < dstHeight; y++) {
171 if (1 != fCodec->getScanlines(pixelPtr, 1, rowBytes)) {
172 fCodec->fillIncompleteImage(info, pixels, rowBytes, options. fZeroInitialized,
173 dstHeight, y + 1);
174 return SkCodec::kIncompleteInput;
175 }
176 int linesToSkip = SkTMin(sampleY - 1, dstHeight - y - 1);
177 if (!fCodec->skipScanlines(linesToSkip)) {
178 fCodec->fillIncompleteImage(info, pixels, rowBytes, options. fZeroInitialized,
179 dstHeight, y + 1);
180 return SkCodec::kIncompleteInput;
181 }
182 pixelPtr = SkTAddOffset<void>(pixelPtr, rowBytes);
183 }
184 return SkCodec::kSuccess;
185 }
186 case SkCodec::kNone_SkScanlineOrder: {
187 const int linesNeeded = subsetHeight - samplingOffsetY;
188 SkAutoMalloc storage(linesNeeded * rowBytes);
189 uint8_t* storagePtr = static_cast<uint8_t*>(storage.get());
190
191 if (!fCodec->skipScanlines(startY)) {
192 fCodec->fillIncompleteImage(info, pixels, rowBytes, options.fZer oInitialized,
193 dstHeight, 0);
194 return SkCodec::kIncompleteInput;
195 }
196 int scanlines = fCodec->getScanlines(storagePtr, linesNeeded, rowByt es);
197
198 for (int y = 0; y < dstHeight; y++) {
199 memcpy(pixels, storagePtr, info.minRowBytes());
200 storagePtr += sampleY * rowBytes;
201 pixels = SkTAddOffset<void>(pixels, rowBytes);
202 }
203
204 if (scanlines < dstHeight) {
205 // fCodec has already handled filling uninitialized memory.
206 return SkCodec::kIncompleteInput;
207 }
208 return SkCodec::kSuccess;
209 }
210 default:
211 SkASSERT(false);
212 return SkCodec::kUnimplemented;
213 }
214 }
OLDNEW
« no previous file with comments | « src/codec/SkSampledCodec.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698