1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/images/transform_scanline.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,140 @@ 1.4 + 1.5 +/* 1.6 + * Copyright 2012 The Android Open Source Project 1.7 + * 1.8 + * Use of this source code is governed by a BSD-style license that can be 1.9 + * found in the LICENSE file. 1.10 + */ 1.11 + 1.12 +/** 1.13 + * Functions to transform scanlines between packed-pixel formats. 1.14 + */ 1.15 + 1.16 +#include "SkBitmap.h" 1.17 +#include "SkColor.h" 1.18 +#include "SkColorPriv.h" 1.19 +#include "SkPreConfig.h" 1.20 +#include "SkUnPreMultiply.h" 1.21 + 1.22 +/** 1.23 + * Function template for transforming scanlines. 1.24 + * Transform 'width' pixels from 'src' buffer into 'dst' buffer, 1.25 + * repacking color channel data as appropriate for the given transformation. 1.26 + */ 1.27 +typedef void (*transform_scanline_proc)(const char* SK_RESTRICT src, 1.28 + int width, char* SK_RESTRICT dst); 1.29 + 1.30 +/** 1.31 + * Identity transformation: just copy bytes from src to dst. 1.32 + */ 1.33 +static void transform_scanline_memcpy(const char* SK_RESTRICT src, int width, 1.34 + char* SK_RESTRICT dst) { 1.35 + memcpy(dst, src, width); 1.36 +} 1.37 + 1.38 +/** 1.39 + * Transform from kRGB_565_Config to 3-bytes-per-pixel RGB. 1.40 + * Alpha channel data is not present in kRGB_565_Config format, so there is no 1.41 + * alpha channel data to preserve. 1.42 + */ 1.43 +static void transform_scanline_565(const char* SK_RESTRICT src, int width, 1.44 + char* SK_RESTRICT dst) { 1.45 + const uint16_t* SK_RESTRICT srcP = (const uint16_t*)src; 1.46 + for (int i = 0; i < width; i++) { 1.47 + unsigned c = *srcP++; 1.48 + *dst++ = SkPacked16ToR32(c); 1.49 + *dst++ = SkPacked16ToG32(c); 1.50 + *dst++ = SkPacked16ToB32(c); 1.51 + } 1.52 +} 1.53 + 1.54 +/** 1.55 + * Transform from kARGB_8888_Config to 3-bytes-per-pixel RGB. 1.56 + * Alpha channel data, if any, is abandoned. 1.57 + */ 1.58 +static void transform_scanline_888(const char* SK_RESTRICT src, int width, 1.59 + char* SK_RESTRICT dst) { 1.60 + const SkPMColor* SK_RESTRICT srcP = (const SkPMColor*)src; 1.61 + for (int i = 0; i < width; i++) { 1.62 + SkPMColor c = *srcP++; 1.63 + *dst++ = SkGetPackedR32(c); 1.64 + *dst++ = SkGetPackedG32(c); 1.65 + *dst++ = SkGetPackedB32(c); 1.66 + } 1.67 +} 1.68 + 1.69 +/** 1.70 + * Transform from kARGB_4444_Config to 3-bytes-per-pixel RGB. 1.71 + * Alpha channel data, if any, is abandoned. 1.72 + */ 1.73 +static void transform_scanline_444(const char* SK_RESTRICT src, int width, 1.74 + char* SK_RESTRICT dst) { 1.75 + const SkPMColor16* SK_RESTRICT srcP = (const SkPMColor16*)src; 1.76 + for (int i = 0; i < width; i++) { 1.77 + SkPMColor16 c = *srcP++; 1.78 + *dst++ = SkPacked4444ToR32(c); 1.79 + *dst++ = SkPacked4444ToG32(c); 1.80 + *dst++ = SkPacked4444ToB32(c); 1.81 + } 1.82 +} 1.83 + 1.84 +/** 1.85 + * Transform from kARGB_8888_Config to 4-bytes-per-pixel RGBA. 1.86 + * (This would be the identity transformation, except for byte-order and 1.87 + * scaling of RGB based on alpha channel). 1.88 + */ 1.89 +static void transform_scanline_8888(const char* SK_RESTRICT src, int width, 1.90 + char* SK_RESTRICT dst) { 1.91 + const SkPMColor* SK_RESTRICT srcP = (const SkPMColor*)src; 1.92 + const SkUnPreMultiply::Scale* SK_RESTRICT table = 1.93 + SkUnPreMultiply::GetScaleTable(); 1.94 + 1.95 + for (int i = 0; i < width; i++) { 1.96 + SkPMColor c = *srcP++; 1.97 + unsigned a = SkGetPackedA32(c); 1.98 + unsigned r = SkGetPackedR32(c); 1.99 + unsigned g = SkGetPackedG32(c); 1.100 + unsigned b = SkGetPackedB32(c); 1.101 + 1.102 + if (0 != a && 255 != a) { 1.103 + SkUnPreMultiply::Scale scale = table[a]; 1.104 + r = SkUnPreMultiply::ApplyScale(scale, r); 1.105 + g = SkUnPreMultiply::ApplyScale(scale, g); 1.106 + b = SkUnPreMultiply::ApplyScale(scale, b); 1.107 + } 1.108 + *dst++ = r; 1.109 + *dst++ = g; 1.110 + *dst++ = b; 1.111 + *dst++ = a; 1.112 + } 1.113 +} 1.114 + 1.115 +/** 1.116 + * Transform from kARGB_8888_Config to 4-bytes-per-pixel RGBA, 1.117 + * with scaling of RGB based on alpha channel. 1.118 + */ 1.119 +static void transform_scanline_4444(const char* SK_RESTRICT src, int width, 1.120 + char* SK_RESTRICT dst) { 1.121 + const SkPMColor16* SK_RESTRICT srcP = (const SkPMColor16*)src; 1.122 + const SkUnPreMultiply::Scale* SK_RESTRICT table = 1.123 + SkUnPreMultiply::GetScaleTable(); 1.124 + 1.125 + for (int i = 0; i < width; i++) { 1.126 + SkPMColor16 c = *srcP++; 1.127 + unsigned a = SkPacked4444ToA32(c); 1.128 + unsigned r = SkPacked4444ToR32(c); 1.129 + unsigned g = SkPacked4444ToG32(c); 1.130 + unsigned b = SkPacked4444ToB32(c); 1.131 + 1.132 + if (0 != a && 255 != a) { 1.133 + SkUnPreMultiply::Scale scale = table[a]; 1.134 + r = SkUnPreMultiply::ApplyScale(scale, r); 1.135 + g = SkUnPreMultiply::ApplyScale(scale, g); 1.136 + b = SkUnPreMultiply::ApplyScale(scale, b); 1.137 + } 1.138 + *dst++ = r; 1.139 + *dst++ = g; 1.140 + *dst++ = b; 1.141 + *dst++ = a; 1.142 + } 1.143 +}