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

Side by Side Diff: tools/android/SkBitmapRegionCanvas.cpp

Issue 1438873002: Move SkBitmapRegionDecoder to include/android and src/android (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Rebase (header guards) 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 | « tools/android/SkBitmapRegionCanvas.h ('k') | tools/android/SkBitmapRegionCodec.h » ('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 * 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 "SkBitmapRegionCanvas.h"
9 #include "SkBitmapRegionDecoderPriv.h"
10 #include "SkCanvas.h"
11 #include "SkCodecPriv.h"
12
13 SkBitmapRegionCanvas::SkBitmapRegionCanvas(SkCodec* decoder)
14 : INHERITED(decoder->getInfo().width(), decoder->getInfo().height())
15 , fDecoder(decoder)
16 {}
17
18 bool SkBitmapRegionCanvas::decodeRegion(SkBitmap* bitmap, SkBRDAllocator* alloca tor,
19 const SkIRect& desiredSubset, int sampleSize, SkColorType dstColorType,
20 bool requireUnpremul) {
21 // Reject color types not supported by this method
22 if (kIndex_8_SkColorType == dstColorType || kGray_8_SkColorType == dstColorT ype) {
23 SkCodecPrintf("Error: Color type not supported.\n");
24 return false;
25 }
26
27 // Reject requests for unpremultiplied alpha
28 if (requireUnpremul) {
29 SkCodecPrintf("Error: Alpha type not supported.\n");
30 return false;
31 }
32 SkAlphaType dstAlphaType = fDecoder->getInfo().alphaType();
33 if (kUnpremul_SkAlphaType == dstAlphaType) {
34 dstAlphaType = kPremul_SkAlphaType;
35 }
36
37 // FIXME: Can we add checks and support kIndex8 or unpremultiplied alpha in special cases?
38
39 // Fix the input sampleSize if necessary.
40 if (sampleSize < 1) {
41 sampleSize = 1;
42 }
43
44 // The size of the output bitmap is determined by the size of the
45 // requested subset, not by the size of the intersection of the subset
46 // and the image dimensions.
47 // If inputX is negative, we will need to place decoded pixels into the
48 // output bitmap starting at a left offset. Call this outX.
49 // If outX is non-zero, subsetX must be zero.
50 // If inputY is negative, we will need to place decoded pixels into the
51 // output bitmap starting at a top offset. Call this outY.
52 // If outY is non-zero, subsetY must be zero.
53 int outX;
54 int outY;
55 SkIRect subset = desiredSubset;
56 SubsetType type = adjust_subset_rect(fDecoder->getInfo().dimensions(), &subs et, &outX, &outY);
57 if (SubsetType::kOutside_SubsetType == type) {
58 return false;
59 }
60
61 // Create the image info for the decode
62 SkImageInfo decodeInfo = SkImageInfo::Make(this->width(), this->height(),
63 dstColorType, dstAlphaType);
64
65 // Start the scanline decoder
66 SkCodec::Result r = fDecoder->startScanlineDecode(decodeInfo);
67 if (SkCodec::kSuccess != r) {
68 SkCodecPrintf("Error: Could not start scanline decoder.\n");
69 return false;
70 }
71
72 // Allocate a bitmap for the unscaled decode
73 SkBitmap tmp;
74 SkImageInfo tmpInfo = decodeInfo.makeWH(this->width(), subset.height());
75 if (!tmp.tryAllocPixels(tmpInfo)) {
76 SkCodecPrintf("Error: Could not allocate pixels.\n");
77 return false;
78 }
79
80 // Skip the unneeded rows
81 if (!fDecoder->skipScanlines(subset.y())) {
82 SkCodecPrintf("Error: Failed to skip scanlines.\n");
83 return false;
84 }
85
86 // Decode the necessary rows
87 fDecoder->getScanlines(tmp.getAddr(0, 0), subset.height(), tmp.rowBytes());
88
89 // Calculate the size of the output
90 const int outWidth = get_scaled_dimension(desiredSubset.width(), sampleSize) ;
91 const int outHeight = get_scaled_dimension(desiredSubset.height(), sampleSiz e);
92
93 // Initialize the destination bitmap
94 SkImageInfo dstInfo = decodeInfo.makeWH(outWidth, outHeight);
95 bitmap->setInfo(dstInfo, dstInfo.minRowBytes());
96 if (!bitmap->tryAllocPixels(allocator, nullptr)) {
97 SkCodecPrintf("Error: Could not allocate pixels.\n");
98 return false;
99 }
100
101 // Zero the bitmap if the region is not completely within the image.
102 // TODO (msarett): Can we make this faster by implementing it to only
103 // zero parts of the image that we won't overwrite with
104 // pixels?
105 if (SubsetType::kPartiallyInside_SubsetType == type) {
106 SkCodec::ZeroInitialized zeroInit = allocator ? allocator->zeroInit() :
107 SkCodec::kNo_ZeroInitialized;
108 if (SkCodec::kNo_ZeroInitialized == zeroInit) {
109 bitmap->eraseColor(0);
110 }
111 }
112
113 // Use a canvas to crop and scale to the destination bitmap
114 SkCanvas canvas(*bitmap);
115 // TODO (msarett): Maybe we can take advantage of the fact that SkRect uses floats?
116 SkRect src = SkRect::MakeXYWH((SkScalar) subset.x(), (SkScalar) 0,
117 (SkScalar) subset.width(), (SkScalar) subset.height());
118 SkRect dst = SkRect::MakeXYWH((SkScalar) (outX / sampleSize), (SkScalar) (ou tY / sampleSize),
119 (SkScalar) get_scaled_dimension(subset.width(), sampleSize),
120 (SkScalar) get_scaled_dimension(subset.height(), sampleSize));
121 SkPaint paint;
122 // Overwrite the dst with the src pixels
123 paint.setXfermodeMode(SkXfermode::kSrc_Mode);
124 // TODO (msarett): Test multiple filter qualities. kNone is the default.
125 canvas.drawBitmapRect(tmp, src, dst, &paint);
126
127 return true;
128 }
129
130 bool SkBitmapRegionCanvas::conversionSupported(SkColorType colorType) {
131 // SkCanvas does not draw to these color types.
132 if (kIndex_8_SkColorType == colorType || kGray_8_SkColorType == colorType) {
133 return false;
134 }
135
136 // FIXME: Call virtual function when it lands.
137 SkImageInfo info = SkImageInfo::Make(0, 0, colorType, fDecoder->getInfo().al phaType(),
138 fDecoder->getInfo().profileType());
139 return conversion_possible(info, fDecoder->getInfo());
140 }
OLDNEW
« no previous file with comments | « tools/android/SkBitmapRegionCanvas.h ('k') | tools/android/SkBitmapRegionCodec.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698