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