SkCodecPriv.h revision cc2feb161f756c4035a407296567654d86bc7be7
1/* 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 11#include "SkColorTable.h" 12#include "SkImageInfo.h" 13#include "SkSwizzler.h" 14#include "SkTypes.h" 15#include "SkUtils.h" 16 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 33static 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 55/* 56 * 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/* 85 * If there is a color table, get a pointer to the colors, otherwise return NULL 86 */ 87static const SkPMColor* get_color_ptr(SkColorTable* colorTable) { 88 return NULL != colorTable ? colorTable->readColors() : NULL; 89} 90 91/* 92 * 93 * Copy the codec color table back to the client when kIndex8 color type is requested 94 */ 95static inline void copy_color_table(const SkImageInfo& dstInfo, SkColorTable* colorTable, 96 SkPMColor* inputColorPtr, int* inputColorCount) { 97 if (kIndex_8_SkColorType == dstInfo.colorType()) { 98 SkASSERT(NULL != inputColorPtr); 99 SkASSERT(NULL != inputColorCount); 100 SkASSERT(NULL != colorTable); 101 memcpy(inputColorPtr, colorTable->readColors(), *inputColorCount * 4); 102 } 103} 104 105/* 106 * Compute row bytes for an image using pixels per byte 107 */ 108static inline size_t compute_row_bytes_ppb(int width, uint32_t pixelsPerByte) { 109 return (width + pixelsPerByte - 1) / pixelsPerByte; 110} 111 112/* 113 * Compute row bytes for an image using bytes per pixel 114 */ 115static inline size_t compute_row_bytes_bpp(int width, uint32_t bytesPerPixel) { 116 return width * bytesPerPixel; 117} 118 119/* 120 * Compute row bytes for an image 121 */ 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/* 135 * Get a byte from a buffer 136 * This method is unsafe, the caller is responsible for performing a check 137 */ 138static inline uint8_t get_byte(uint8_t* buffer, uint32_t i) { 139 return buffer[i]; 140} 141 142/* 143 * Get a short from a buffer 144 * This method is unsafe, the caller is responsible for performing a check 145 */ 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/* 157 * Get an int from a buffer 158 * This method is unsafe, the caller is responsible for performing a check 159 */ 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 170#ifdef SK_PRINT_CODEC_MESSAGES 171 #define SkCodecPrintf SkDebugf 172#else 173 #define SkCodecPrintf(...) 174#endif 175 176#endif // SkCodecPriv_DEFINED 177