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 
profile_type_is_valid(SkColorProfileType profileType)12 static bool profile_type_is_valid(SkColorProfileType profileType) {
13     return (profileType >= 0) && (profileType <= kLastEnum_SkColorProfileType);
14 }
15 
alpha_type_is_valid(SkAlphaType alphaType)16 static bool alpha_type_is_valid(SkAlphaType alphaType) {
17     return (alphaType >= 0) && (alphaType <= kLastEnum_SkAlphaType);
18 }
19 
color_type_is_valid(SkColorType colorType)20 static bool color_type_is_valid(SkColorType colorType) {
21     return (colorType >= 0) && (colorType <= kLastEnum_SkColorType);
22 }
23 
unflatten(SkReadBuffer & buffer)24 void SkImageInfo::unflatten(SkReadBuffer& buffer) {
25     fWidth = buffer.read32();
26     fHeight = buffer.read32();
27 
28     uint32_t packed = buffer.read32();
29     SkASSERT(0 == (packed >> 24));
30     fProfileType = (SkColorProfileType)((packed >> 16) & 0xFF);
31     fAlphaType = (SkAlphaType)((packed >> 8) & 0xFF);
32     fColorType = (SkColorType)((packed >> 0) & 0xFF);
33     buffer.validate(profile_type_is_valid(fProfileType) &&
34                     alpha_type_is_valid(fAlphaType) &&
35                     color_type_is_valid(fColorType));
36 }
37 
flatten(SkWriteBuffer & buffer) const38 void SkImageInfo::flatten(SkWriteBuffer& buffer) const {
39     buffer.write32(fWidth);
40     buffer.write32(fHeight);
41 
42     SkASSERT(0 == (fProfileType & ~0xFF));
43     SkASSERT(0 == (fAlphaType & ~0xFF));
44     SkASSERT(0 == (fColorType & ~0xFF));
45     uint32_t packed = (fProfileType << 16) | (fAlphaType << 8) | fColorType;
46     buffer.write32(packed);
47 }
48 
SkColorTypeValidateAlphaType(SkColorType colorType,SkAlphaType alphaType,SkAlphaType * canonical)49 bool SkColorTypeValidateAlphaType(SkColorType colorType, SkAlphaType alphaType,
50                                   SkAlphaType* canonical) {
51     switch (colorType) {
52         case kUnknown_SkColorType:
53             alphaType = kUnknown_SkAlphaType;
54             break;
55         case kAlpha_8_SkColorType:
56             if (kUnpremul_SkAlphaType == alphaType) {
57                 alphaType = kPremul_SkAlphaType;
58             }
59             // fall-through
60         case kIndex_8_SkColorType:
61         case kARGB_4444_SkColorType:
62         case kRGBA_8888_SkColorType:
63         case kBGRA_8888_SkColorType:
64         case kRGBA_F16_SkColorType:
65             if (kUnknown_SkAlphaType == alphaType) {
66                 return false;
67             }
68             break;
69         case kRGB_565_SkColorType:
70         case kGray_8_SkColorType:
71             alphaType = kOpaque_SkAlphaType;
72             break;
73         default:
74             return false;
75     }
76     if (canonical) {
77         *canonical = alphaType;
78     }
79     return true;
80 }
81 
82 ///////////////////////////////////////////////////////////////////////////////////////////////////
83 
84 #include "SkReadPixelsRec.h"
85 
trim(int srcWidth,int srcHeight)86 bool SkReadPixelsRec::trim(int srcWidth, int srcHeight) {
87     switch (fInfo.colorType()) {
88         case kUnknown_SkColorType:
89         case kIndex_8_SkColorType:
90             return false;
91         default:
92             break;
93     }
94     if (nullptr == fPixels || fRowBytes < fInfo.minRowBytes()) {
95         return false;
96     }
97     if (0 == fInfo.width() || 0 == fInfo.height()) {
98         return false;
99     }
100 
101     int x = fX;
102     int y = fY;
103     SkIRect srcR = SkIRect::MakeXYWH(x, y, fInfo.width(), fInfo.height());
104     if (!srcR.intersect(0, 0, srcWidth, srcHeight)) {
105         return false;
106     }
107 
108     // if x or y are negative, then we have to adjust pixels
109     if (x > 0) {
110         x = 0;
111     }
112     if (y > 0) {
113         y = 0;
114     }
115     // here x,y are either 0 or negative
116     fPixels = ((char*)fPixels - y * fRowBytes - x * fInfo.bytesPerPixel());
117     // the intersect may have shrunk info's logical size
118     fInfo = fInfo.makeWH(srcR.width(), srcR.height());
119     fX = srcR.x();
120     fY = srcR.y();
121 
122     return true;
123 }
124 
125