blob: 7a2558ebd3f992ea0c34a1523cc2eeb33cf37231 [file] [log] [blame]
reed@google.comf309dbc2013-12-09 22:09:41 +00001/*
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"
halcanary484b3d02016-04-25 10:32:23 -07009#include "SkImageInfoPriv.h"
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +000010#include "SkReadBuffer.h"
11#include "SkWriteBuffer.h"
reed@google.comf309dbc2013-12-09 22:09:41 +000012
halcanary484b3d02016-04-25 10:32:23 -070013// Indicate how images and gradients should interpret colors by default.
herb835acc72016-05-17 06:50:15 -070014bool gDefaultProfileIsSRGB;
halcanary484b3d02016-04-25 10:32:23 -070015
16SkColorProfileType SkDefaultColorProfile() {
17 return gDefaultProfileIsSRGB ? kSRGB_SkColorProfileType
18 : kLinear_SkColorProfileType;
19}
herb9bc22352016-04-20 15:07:32 -070020
reed7c748852014-11-10 08:57:21 -080021static bool profile_type_is_valid(SkColorProfileType profileType) {
22 return (profileType >= 0) && (profileType <= kLastEnum_SkColorProfileType);
23}
24
reed2bdf1f52014-09-03 05:48:56 -070025static bool alpha_type_is_valid(SkAlphaType alphaType) {
26 return (alphaType >= 0) && (alphaType <= kLastEnum_SkAlphaType);
commit-bot@chromium.orgef74fa12013-12-17 20:49:46 +000027}
28
reed2bdf1f52014-09-03 05:48:56 -070029static bool color_type_is_valid(SkColorType colorType) {
30 return (colorType >= 0) && (colorType <= kLastEnum_SkColorType);
commit-bot@chromium.orgef74fa12013-12-17 20:49:46 +000031}
32
msarett23c51102016-05-27 07:39:02 -070033SkImageInfo SkImageInfo::Make(int width, int height, SkColorType ct, SkAlphaType at,
34 sk_sp<SkColorSpace> cs) {
35 return SkImageInfo(width, height, ct, at, SkDefaultColorProfile(), std::move(cs));
36}
37
reedfbce71f2016-06-02 12:40:22 -070038SkImageInfo SkImageInfo::MakeS32(int width, int height, SkAlphaType at) {
39 return SkImageInfo(width, height, kN32_SkColorType, at, kSRGB_SkColorProfileType,
40 SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named));
41}
42
reed2bdf1f52014-09-03 05:48:56 -070043void SkImageInfo::unflatten(SkReadBuffer& buffer) {
44 fWidth = buffer.read32();
45 fHeight = buffer.read32();
46
47 uint32_t packed = buffer.read32();
reed7c748852014-11-10 08:57:21 -080048 SkASSERT(0 == (packed >> 24));
49 fProfileType = (SkColorProfileType)((packed >> 16) & 0xFF);
reed2bdf1f52014-09-03 05:48:56 -070050 fAlphaType = (SkAlphaType)((packed >> 8) & 0xFF);
51 fColorType = (SkColorType)((packed >> 0) & 0xFF);
reed7c748852014-11-10 08:57:21 -080052 buffer.validate(profile_type_is_valid(fProfileType) &&
53 alpha_type_is_valid(fAlphaType) &&
reed2bdf1f52014-09-03 05:48:56 -070054 color_type_is_valid(fColorType));
reed@google.comf309dbc2013-12-09 22:09:41 +000055}
56
reed2bdf1f52014-09-03 05:48:56 -070057void SkImageInfo::flatten(SkWriteBuffer& buffer) const {
58 buffer.write32(fWidth);
59 buffer.write32(fHeight);
reed@google.comf309dbc2013-12-09 22:09:41 +000060
reed7c748852014-11-10 08:57:21 -080061 SkASSERT(0 == (fProfileType & ~0xFF));
reed2bdf1f52014-09-03 05:48:56 -070062 SkASSERT(0 == (fAlphaType & ~0xFF));
63 SkASSERT(0 == (fColorType & ~0xFF));
reed7c748852014-11-10 08:57:21 -080064 uint32_t packed = (fProfileType << 16) | (fAlphaType << 8) | fColorType;
reed2bdf1f52014-09-03 05:48:56 -070065 buffer.write32(packed);
reed@google.comf309dbc2013-12-09 22:09:41 +000066}
scroggo2fd0d142014-07-01 07:08:19 -070067
68bool SkColorTypeValidateAlphaType(SkColorType colorType, SkAlphaType alphaType,
69 SkAlphaType* canonical) {
70 switch (colorType) {
71 case kUnknown_SkColorType:
reed44977482015-02-27 10:23:00 -080072 alphaType = kUnknown_SkAlphaType;
scroggo2fd0d142014-07-01 07:08:19 -070073 break;
74 case kAlpha_8_SkColorType:
75 if (kUnpremul_SkAlphaType == alphaType) {
76 alphaType = kPremul_SkAlphaType;
77 }
78 // fall-through
79 case kIndex_8_SkColorType:
80 case kARGB_4444_SkColorType:
81 case kRGBA_8888_SkColorType:
82 case kBGRA_8888_SkColorType:
reed9e01ac72016-02-06 20:38:45 -080083 case kRGBA_F16_SkColorType:
reed44977482015-02-27 10:23:00 -080084 if (kUnknown_SkAlphaType == alphaType) {
scroggo2fd0d142014-07-01 07:08:19 -070085 return false;
86 }
87 break;
88 case kRGB_565_SkColorType:
reed0c9b1a82015-03-17 17:44:06 -070089 case kGray_8_SkColorType:
scroggo2fd0d142014-07-01 07:08:19 -070090 alphaType = kOpaque_SkAlphaType;
91 break;
92 default:
93 return false;
94 }
95 if (canonical) {
96 *canonical = alphaType;
97 }
98 return true;
99}
reed96472de2014-12-10 09:53:42 -0800100
101///////////////////////////////////////////////////////////////////////////////////////////////////
102
103#include "SkReadPixelsRec.h"
104
105bool SkReadPixelsRec::trim(int srcWidth, int srcHeight) {
106 switch (fInfo.colorType()) {
107 case kUnknown_SkColorType:
108 case kIndex_8_SkColorType:
109 return false;
110 default:
111 break;
112 }
halcanary96fcdcc2015-08-27 07:41:13 -0700113 if (nullptr == fPixels || fRowBytes < fInfo.minRowBytes()) {
reed96472de2014-12-10 09:53:42 -0800114 return false;
115 }
116 if (0 == fInfo.width() || 0 == fInfo.height()) {
117 return false;
118 }
119
120 int x = fX;
121 int y = fY;
122 SkIRect srcR = SkIRect::MakeXYWH(x, y, fInfo.width(), fInfo.height());
123 if (!srcR.intersect(0, 0, srcWidth, srcHeight)) {
124 return false;
125 }
126
127 // if x or y are negative, then we have to adjust pixels
128 if (x > 0) {
129 x = 0;
130 }
131 if (y > 0) {
132 y = 0;
133 }
134 // here x,y are either 0 or negative
135 fPixels = ((char*)fPixels - y * fRowBytes - x * fInfo.bytesPerPixel());
136 // the intersect may have shrunk info's logical size
137 fInfo = fInfo.makeWH(srcR.width(), srcR.height());
138 fX = srcR.x();
139 fY = srcR.y();
140
141 return true;
142}