Line data Source code
1 : /*
2 : * Copyright 2010 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 "SkImageInfo.h"
9 : #include "SkReadBuffer.h"
10 : #include "SkWriteBuffer.h"
11 :
12 0 : static bool alpha_type_is_valid(SkAlphaType alphaType) {
13 0 : return (alphaType >= 0) && (alphaType <= kLastEnum_SkAlphaType);
14 : }
15 :
16 0 : static bool color_type_is_valid(SkColorType colorType) {
17 0 : return (colorType >= 0) && (colorType <= kLastEnum_SkColorType);
18 : }
19 :
20 0 : SkImageInfo SkImageInfo::MakeS32(int width, int height, SkAlphaType at) {
21 : return SkImageInfo(width, height, kN32_SkColorType, at,
22 0 : SkColorSpace::MakeSRGB());
23 : }
24 :
25 : static const int kColorTypeMask = 0x0F;
26 : static const int kAlphaTypeMask = 0x03;
27 :
28 0 : void SkImageInfo::unflatten(SkReadBuffer& buffer) {
29 0 : fWidth = buffer.read32();
30 0 : fHeight = buffer.read32();
31 :
32 0 : uint32_t packed = buffer.read32();
33 0 : fColorType = (SkColorType)((packed >> 0) & kColorTypeMask);
34 0 : fAlphaType = (SkAlphaType)((packed >> 8) & kAlphaTypeMask);
35 0 : buffer.validate(alpha_type_is_valid(fAlphaType) && color_type_is_valid(fColorType));
36 :
37 0 : sk_sp<SkData> data = buffer.readByteArrayAsData();
38 0 : fColorSpace = SkColorSpace::Deserialize(data->data(), data->size());
39 0 : }
40 :
41 0 : void SkImageInfo::flatten(SkWriteBuffer& buffer) const {
42 0 : buffer.write32(fWidth);
43 0 : buffer.write32(fHeight);
44 :
45 0 : SkASSERT(0 == (fAlphaType & ~kAlphaTypeMask));
46 0 : SkASSERT(0 == (fColorType & ~kColorTypeMask));
47 0 : uint32_t packed = (fAlphaType << 8) | fColorType;
48 0 : buffer.write32(packed);
49 :
50 0 : if (fColorSpace) {
51 0 : sk_sp<SkData> data = fColorSpace->serialize();
52 0 : if (data) {
53 0 : buffer.writeDataAsByteArray(data.get());
54 : } else {
55 0 : buffer.writeByteArray(nullptr, 0);
56 : }
57 : } else {
58 0 : sk_sp<SkData> data = SkData::MakeEmpty();
59 0 : buffer.writeDataAsByteArray(data.get());
60 : }
61 0 : }
62 :
63 662 : bool SkColorTypeValidateAlphaType(SkColorType colorType, SkAlphaType alphaType,
64 : SkAlphaType* canonical) {
65 662 : switch (colorType) {
66 : case kUnknown_SkColorType:
67 0 : alphaType = kUnknown_SkAlphaType;
68 0 : break;
69 : case kAlpha_8_SkColorType:
70 16 : if (kUnpremul_SkAlphaType == alphaType) {
71 0 : alphaType = kPremul_SkAlphaType;
72 : }
73 : // fall-through
74 : case kIndex_8_SkColorType:
75 : case kARGB_4444_SkColorType:
76 : case kRGBA_8888_SkColorType:
77 : case kBGRA_8888_SkColorType:
78 : case kRGBA_F16_SkColorType:
79 662 : if (kUnknown_SkAlphaType == alphaType) {
80 0 : return false;
81 : }
82 662 : break;
83 : case kRGB_565_SkColorType:
84 : case kGray_8_SkColorType:
85 0 : alphaType = kOpaque_SkAlphaType;
86 0 : break;
87 : default:
88 0 : return false;
89 : }
90 662 : if (canonical) {
91 662 : *canonical = alphaType;
92 : }
93 662 : return true;
94 : }
95 :
96 : ///////////////////////////////////////////////////////////////////////////////////////////////////
97 :
98 : #include "SkReadPixelsRec.h"
99 :
100 0 : bool SkReadPixelsRec::trim(int srcWidth, int srcHeight) {
101 0 : if (nullptr == fPixels || fRowBytes < fInfo.minRowBytes()) {
102 0 : return false;
103 : }
104 0 : if (0 >= fInfo.width() || 0 >= fInfo.height()) {
105 0 : return false;
106 : }
107 :
108 0 : int x = fX;
109 0 : int y = fY;
110 0 : SkIRect srcR = SkIRect::MakeXYWH(x, y, fInfo.width(), fInfo.height());
111 0 : if (!srcR.intersect(0, 0, srcWidth, srcHeight)) {
112 0 : return false;
113 : }
114 :
115 : // if x or y are negative, then we have to adjust pixels
116 0 : if (x > 0) {
117 0 : x = 0;
118 : }
119 0 : if (y > 0) {
120 0 : y = 0;
121 : }
122 : // here x,y are either 0 or negative
123 0 : fPixels = ((char*)fPixels - y * fRowBytes - x * fInfo.bytesPerPixel());
124 : // the intersect may have shrunk info's logical size
125 0 : fInfo = fInfo.makeWH(srcR.width(), srcR.height());
126 0 : fX = srcR.x();
127 0 : fY = srcR.y();
128 :
129 0 : return true;
130 : }
131 :
132 : ///////////////////////////////////////////////////////////////////////////////////////////////////
133 :
134 : #include "SkWritePixelsRec.h"
135 :
136 0 : bool SkWritePixelsRec::trim(int dstWidth, int dstHeight) {
137 0 : if (nullptr == fPixels || fRowBytes < fInfo.minRowBytes()) {
138 0 : return false;
139 : }
140 0 : if (0 >= fInfo.width() || 0 >= fInfo.height()) {
141 0 : return false;
142 : }
143 :
144 0 : int x = fX;
145 0 : int y = fY;
146 0 : SkIRect dstR = SkIRect::MakeXYWH(x, y, fInfo.width(), fInfo.height());
147 0 : if (!dstR.intersect(0, 0, dstWidth, dstHeight)) {
148 0 : return false;
149 : }
150 :
151 : // if x or y are negative, then we have to adjust pixels
152 0 : if (x > 0) {
153 0 : x = 0;
154 : }
155 0 : if (y > 0) {
156 0 : y = 0;
157 : }
158 : // here x,y are either 0 or negative
159 0 : fPixels = ((const char*)fPixels - y * fRowBytes - x * fInfo.bytesPerPixel());
160 : // the intersect may have shrunk info's logical size
161 0 : fInfo = fInfo.makeWH(dstR.width(), dstR.height());
162 0 : fX = dstR.x();
163 0 : fY = dstR.y();
164 :
165 0 : return true;
166 : }
|