1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
/*
* Copyright 2014 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "SkTextureCompressor.h"
#include "SkTextureCompressor_R11EAC.h"
#include "SkTextureCompressor_LATC.h"
#include "SkBitmap.h"
#include "SkData.h"
#include "SkEndian.h"
#include "SkTextureCompression_opts.h"
////////////////////////////////////////////////////////////////////////////////
namespace SkTextureCompressor {
int GetCompressedDataSize(Format fmt, int width, int height) {
switch (fmt) {
// These formats are 64 bits per 4x4 block.
case kR11_EAC_Format:
case kLATC_Format:
{
static const int kBlockDimension = 4;
static const int kEncodedBlockSize = 8;
if(((width % kBlockDimension) == 0) && ((height % kBlockDimension) == 0)) {
const int blocksX = width / kBlockDimension;
const int blocksY = height / kBlockDimension;
return blocksX * blocksY * kEncodedBlockSize;
}
return -1;
}
default:
SkFAIL("Unknown compressed format!");
return -1;
}
}
bool CompressBufferToFormat(uint8_t* dst, const uint8_t* src, SkColorType srcColorType,
int width, int height, int rowBytes, Format format, bool opt) {
CompressionProc proc = NULL;
if (opt) {
proc = SkTextureCompressorGetPlatformProc(srcColorType, format);
}
if (NULL == proc) {
switch (srcColorType) {
case kAlpha_8_SkColorType:
{
switch (format) {
case kLATC_Format:
proc = CompressA8ToLATC;
break;
case kR11_EAC_Format:
proc = CompressA8ToR11EAC;
break;
default:
// Do nothing...
break;
}
}
break;
default:
// Do nothing...
break;
}
}
if (NULL != proc) {
return proc(dst, src, width, height, rowBytes);
}
return false;
}
SkData *CompressBitmapToFormat(const SkBitmap &bitmap, Format format) {
SkAutoLockPixels alp(bitmap);
int compressedDataSize = GetCompressedDataSize(format, bitmap.width(), bitmap.height());
if (compressedDataSize < 0) {
return NULL;
}
const uint8_t* src = reinterpret_cast<const uint8_t*>(bitmap.getPixels());
uint8_t* dst = reinterpret_cast<uint8_t*>(sk_malloc_throw(compressedDataSize));
if (CompressBufferToFormat(dst, src, bitmap.colorType(), bitmap.width(), bitmap.height(),
bitmap.rowBytes(), format)) {
return SkData::NewFromMalloc(dst, compressedDataSize);
}
sk_free(dst);
return NULL;
}
SkBlitter* CreateBlitterForFormat(int width, int height, void* compressedBuffer, Format format) {
switch(format) {
case kLATC_Format:
return CreateLATCBlitter(width, height, compressedBuffer);
case kR11_EAC_Format:
return CreateR11EACBlitter(width, height, compressedBuffer);
default:
return NULL;
}
return NULL;
}
} // namespace SkTextureCompressor
|