blob: 9a28cfdda1690df3268b02198930bd8db2144135 [file] [log] [blame]
msarett74114382015-03-16 11:55:18 -07001/*
2 * Copyright 2015 The Android Open Source Project
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#ifndef SkCodecPriv_DEFINED
9#define SkCodecPriv_DEFINED
10
msarett9e43cab2015-04-29 07:38:43 -070011#include "SkColorTable.h"
msarett74114382015-03-16 11:55:18 -070012#include "SkImageInfo.h"
13#include "SkSwizzler.h"
14#include "SkTypes.h"
msarett9e43cab2015-04-29 07:38:43 -070015#include "SkUtils.h"
msarett74114382015-03-16 11:55:18 -070016
17/*
18 *
19 * Helper routine for alpha result codes
20 *
21 */
22#define INIT_RESULT_ALPHA \
23 uint8_t zeroAlpha = 0; \
24 uint8_t maxAlpha = 0xFF;
25
26#define UPDATE_RESULT_ALPHA(alpha) \
27 zeroAlpha |= (alpha); \
28 maxAlpha &= (alpha);
29
30#define COMPUTE_RESULT_ALPHA \
31 SkSwizzler::GetResult(zeroAlpha, maxAlpha);
32
msarett4ab9d5f2015-08-06 15:34:42 -070033static inline bool valid_alpha(SkAlphaType dstAlpha, SkAlphaType srcAlpha) {
34 // Check for supported alpha types
35 if (srcAlpha != dstAlpha) {
36 if (kOpaque_SkAlphaType == srcAlpha) {
37 // If the source is opaque, we must decode to opaque
38 return false;
39 }
40
41 // The source is not opaque
42 switch (dstAlpha) {
43 case kPremul_SkAlphaType:
44 case kUnpremul_SkAlphaType:
45 // The source is not opaque, so either of these is okay
46 break;
47 default:
48 // We cannot decode a non-opaque image to opaque (or unknown)
49 return false;
50 }
51 }
52 return true;
53}
54
msarett74114382015-03-16 11:55:18 -070055/*
scroggocc2feb12015-08-14 08:32:46 -070056 * Most of our codecs support the same conversions:
57 * - profileType must be the same
58 * - opaque only to opaque (and 565 only if opaque)
59 * - premul to unpremul and vice versa
60 * - always support N32
61 * - otherwise match the src color type
62 */
63static bool conversion_possible(const SkImageInfo& dst, const SkImageInfo& src) {
64 if (dst.profileType() != src.profileType()) {
65 return false;
66 }
67
68 // Ensure the alpha type is valid
69 if (!valid_alpha(dst.alphaType(), src.alphaType())) {
70 return false;
71 }
72
73 // Check for supported color types
74 switch (dst.colorType()) {
75 case kN32_SkColorType:
76 return true;
77 case kRGB_565_SkColorType:
78 return src.alphaType() == kOpaque_SkAlphaType;
79 default:
80 return dst.colorType() == src.colorType();
81 }
82}
83
84/*
halcanary96fcdcc2015-08-27 07:41:13 -070085 * If there is a color table, get a pointer to the colors, otherwise return nullptr
msarett99f567e2015-08-05 12:58:26 -070086 */
87static const SkPMColor* get_color_ptr(SkColorTable* colorTable) {
halcanary96fcdcc2015-08-27 07:41:13 -070088 return nullptr != colorTable ? colorTable->readColors() : nullptr;
msarett99f567e2015-08-05 12:58:26 -070089}
90
91/*
msarett74114382015-03-16 11:55:18 -070092 *
msarett9e43cab2015-04-29 07:38:43 -070093 * Copy the codec color table back to the client when kIndex8 color type is requested
msarett9e43cab2015-04-29 07:38:43 -070094 */
95static inline void copy_color_table(const SkImageInfo& dstInfo, SkColorTable* colorTable,
96 SkPMColor* inputColorPtr, int* inputColorCount) {
97 if (kIndex_8_SkColorType == dstInfo.colorType()) {
halcanary96fcdcc2015-08-27 07:41:13 -070098 SkASSERT(nullptr != inputColorPtr);
99 SkASSERT(nullptr != inputColorCount);
100 SkASSERT(nullptr != colorTable);
mtklein58fd2c82015-07-27 11:08:28 -0700101 memcpy(inputColorPtr, colorTable->readColors(), *inputColorCount * 4);
msarett9e43cab2015-04-29 07:38:43 -0700102 }
103}
104
105/*
msarett74114382015-03-16 11:55:18 -0700106 * Compute row bytes for an image using pixels per byte
msarett74114382015-03-16 11:55:18 -0700107 */
108static inline size_t compute_row_bytes_ppb(int width, uint32_t pixelsPerByte) {
109 return (width + pixelsPerByte - 1) / pixelsPerByte;
110}
111
112/*
msarett74114382015-03-16 11:55:18 -0700113 * Compute row bytes for an image using bytes per pixel
msarett74114382015-03-16 11:55:18 -0700114 */
115static inline size_t compute_row_bytes_bpp(int width, uint32_t bytesPerPixel) {
116 return width * bytesPerPixel;
117}
118
119/*
msarett74114382015-03-16 11:55:18 -0700120 * Compute row bytes for an image
msarett74114382015-03-16 11:55:18 -0700121 */
122static inline size_t compute_row_bytes(int width, uint32_t bitsPerPixel) {
123 if (bitsPerPixel < 16) {
124 SkASSERT(0 == 8 % bitsPerPixel);
125 const uint32_t pixelsPerByte = 8 / bitsPerPixel;
126 return compute_row_bytes_ppb(width, pixelsPerByte);
127 } else {
128 SkASSERT(0 == bitsPerPixel % 8);
129 const uint32_t bytesPerPixel = bitsPerPixel / 8;
130 return compute_row_bytes_bpp(width, bytesPerPixel);
131 }
132}
133
134/*
msarett74114382015-03-16 11:55:18 -0700135 * Get a byte from a buffer
136 * This method is unsafe, the caller is responsible for performing a check
msarett74114382015-03-16 11:55:18 -0700137 */
138static inline uint8_t get_byte(uint8_t* buffer, uint32_t i) {
139 return buffer[i];
140}
141
142/*
msarett74114382015-03-16 11:55:18 -0700143 * Get a short from a buffer
144 * This method is unsafe, the caller is responsible for performing a check
msarett74114382015-03-16 11:55:18 -0700145 */
146static inline uint16_t get_short(uint8_t* buffer, uint32_t i) {
147 uint16_t result;
148 memcpy(&result, &(buffer[i]), 2);
149#ifdef SK_CPU_BENDIAN
150 return SkEndianSwap16(result);
151#else
152 return result;
153#endif
154}
155
156/*
msarett74114382015-03-16 11:55:18 -0700157 * Get an int from a buffer
158 * This method is unsafe, the caller is responsible for performing a check
msarett74114382015-03-16 11:55:18 -0700159 */
160static inline uint32_t get_int(uint8_t* buffer, uint32_t i) {
161 uint32_t result;
162 memcpy(&result, &(buffer[i]), 4);
163#ifdef SK_CPU_BENDIAN
164 return SkEndianSwap32(result);
165#else
166 return result;
167#endif
168}
169
scroggo230d4ac2015-03-26 07:15:55 -0700170#ifdef SK_PRINT_CODEC_MESSAGES
171 #define SkCodecPrintf SkDebugf
172#else
173 #define SkCodecPrintf(...)
174#endif
175
msarett74114382015-03-16 11:55:18 -0700176#endif // SkCodecPriv_DEFINED