Flutter Engine
The Flutter Engine
etc1.cpp
Go to the documentation of this file.
1// Copyright 2009 Google Inc.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//////////////////////////////////////////////////////////////////////////////////////////
16
17// This is a fork of the AOSP project ETC1 codec. The original code can be found
18// at the following web site:
19// https://android.googlesource.com/platform/frameworks/native/+/master/opengl/include/ETC1/
20
21//////////////////////////////////////////////////////////////////////////////////////////
22
24
25#include <cstring>
26
27/* From http://www.khronos.org/registry/gles/extensions/OES/OES_compressed_ETC1_RGB8_texture.txt
28
29 The number of bits that represent a 4x4 texel block is 64 bits if
30 <internalformat> is given by ETC1_RGB8_OES.
31
32 The data for a block is a number of bytes,
33
34 {q0, q1, q2, q3, q4, q5, q6, q7}
35
36 where byte q0 is located at the lowest memory address and q7 at
37 the highest. The 64 bits specifying the block is then represented
38 by the following 64 bit integer:
39
40 int64bit = 256*(256*(256*(256*(256*(256*(256*q0+q1)+q2)+q3)+q4)+q5)+q6)+q7;
41
42 ETC1_RGB8_OES:
43
44 a) bit layout in bits 63 through 32 if diffbit = 0
45
46 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48
47 -----------------------------------------------
48 | base col1 | base col2 | base col1 | base col2 |
49 | R1 (4bits)| R2 (4bits)| G1 (4bits)| G2 (4bits)|
50 -----------------------------------------------
51
52 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32
53 ---------------------------------------------------
54 | base col1 | base col2 | table | table |diff|flip|
55 | B1 (4bits)| B2 (4bits)| cw 1 | cw 2 |bit |bit |
56 ---------------------------------------------------
57
58
59 b) bit layout in bits 63 through 32 if diffbit = 1
60
61 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48
62 -----------------------------------------------
63 | base col1 | dcol 2 | base col1 | dcol 2 |
64 | R1' (5 bits) | dR2 | G1' (5 bits) | dG2 |
65 -----------------------------------------------
66
67 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32
68 ---------------------------------------------------
69 | base col 1 | dcol 2 | table | table |diff|flip|
70 | B1' (5 bits) | dB2 | cw 1 | cw 2 |bit |bit |
71 ---------------------------------------------------
72
73
74 c) bit layout in bits 31 through 0 (in both cases)
75
76 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16
77 -----------------------------------------------
78 | most significant pixel index bits |
79 | p| o| n| m| l| k| j| i| h| g| f| e| d| c| b| a|
80 -----------------------------------------------
81
82 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
83 --------------------------------------------------
84 | least significant pixel index bits |
85 | p| o| n| m| l| k| j| i| h| g| f| e| d| c | b | a |
86 --------------------------------------------------
87
88
89 Add table 3.17.2: Intensity modifier sets for ETC1 compressed textures:
90
91 table codeword modifier table
92 ------------------ ----------------------
93 0 -8 -2 2 8
94 1 -17 -5 5 17
95 2 -29 -9 9 29
96 3 -42 -13 13 42
97 4 -60 -18 18 60
98 5 -80 -24 24 80
99 6 -106 -33 33 106
100 7 -183 -47 47 183
101
102
103 Add table 3.17.3 Mapping from pixel index values to modifier values for
104 ETC1 compressed textures:
105
106 pixel index value
107 ---------------
108 msb lsb resulting modifier value
109 ----- ----- -------------------------
110 1 1 -b (large negative value)
111 1 0 -a (small negative value)
112 0 0 a (small positive value)
113 0 1 b (large positive value)
114
115
116 */
117
118static const int kModifierTable[] = {
119/* 0 */2, 8, -2, -8,
120/* 1 */5, 17, -5, -17,
121/* 2 */9, 29, -9, -29,
122/* 3 */13, 42, -13, -42,
123/* 4 */18, 60, -18, -60,
124/* 5 */24, 80, -24, -80,
125/* 6 */33, 106, -33, -106,
126/* 7 */47, 183, -47, -183 };
127
128static const int kLookup[8] = { 0, 1, 2, 3, -4, -3, -2, -1 };
129
130static inline etc1_byte clamp(int x) {
131 return (etc1_byte) (x >= 0 ? (x < 255 ? x : 255) : 0);
132}
133
134static
135inline int convert4To8(int b) {
136 int c = b & 0xf;
137 return (c << 4) | c;
138}
139
140static
141inline int convert5To8(int b) {
142 int c = b & 0x1f;
143 return (c << 3) | (c >> 2);
144}
145
146static
147inline int convert6To8(int b) {
148 int c = b & 0x3f;
149 return (c << 2) | (c >> 4);
150}
151
152static
153inline int divideBy255(int d) {
154 return (d + 128 + (d >> 8)) >> 8;
155}
156
157static
158inline int convert8To4(int b) {
159 int c = b & 0xff;
160 return divideBy255(c * 15);
161}
162
163static
164inline int convert8To5(int b) {
165 int c = b & 0xff;
166 return divideBy255(c * 31);
167}
168
169static
170inline int convertDiff(int base, int diff) {
171 return convert5To8((0x1f & base) + kLookup[0x7 & diff]);
172}
173
174static
175void decode_subblock(etc1_byte* pOut, int r, int g, int b, const int* table,
176 etc1_uint32 low, bool second, bool flipped) {
177 int baseX = 0;
178 int baseY = 0;
179 if (second) {
180 if (flipped) {
181 baseY = 2;
182 } else {
183 baseX = 2;
184 }
185 }
186 for (int i = 0; i < 8; i++) {
187 int x, y;
188 if (flipped) {
189 x = baseX + (i >> 1);
190 y = baseY + (i & 1);
191 } else {
192 x = baseX + (i >> 2);
193 y = baseY + (i & 3);
194 }
195 int k = y + (x * 4);
196 int offset = ((low >> k) & 1) | ((low >> (k + 15)) & 2);
197 int delta = table[offset];
198 etc1_byte* q = pOut + 3 * (x + 4 * y);
199 *q++ = clamp(r + delta);
200 *q++ = clamp(g + delta);
201 *q++ = clamp(b + delta);
202 }
203}
204
205// Input is an ETC1 compressed version of the data.
206// Output is a 4 x 4 square of 3-byte pixels in form R, G, B
207
208void etc1_decode_block(const etc1_byte* pIn, etc1_byte* pOut) {
209 etc1_uint32 high = (pIn[0] << 24) | (pIn[1] << 16) | (pIn[2] << 8) | pIn[3];
210 etc1_uint32 low = (pIn[4] << 24) | (pIn[5] << 16) | (pIn[6] << 8) | pIn[7];
211 int r1, r2, g1, g2, b1, b2;
212 if (high & 2) {
213 // differential
214 int rBase = high >> 27;
215 int gBase = high >> 19;
216 int bBase = high >> 11;
217 r1 = convert5To8(rBase);
218 r2 = convertDiff(rBase, high >> 24);
219 g1 = convert5To8(gBase);
220 g2 = convertDiff(gBase, high >> 16);
221 b1 = convert5To8(bBase);
222 b2 = convertDiff(bBase, high >> 8);
223 } else {
224 // not differential
225 r1 = convert4To8(high >> 28);
226 r2 = convert4To8(high >> 24);
227 g1 = convert4To8(high >> 20);
228 g2 = convert4To8(high >> 16);
229 b1 = convert4To8(high >> 12);
230 b2 = convert4To8(high >> 8);
231 }
232 int tableIndexA = 7 & (high >> 5);
233 int tableIndexB = 7 & (high >> 2);
234 const int* tableA = kModifierTable + tableIndexA * 4;
235 const int* tableB = kModifierTable + tableIndexB * 4;
236 bool flipped = (high & 1) != 0;
237 decode_subblock(pOut, r1, g1, b1, tableA, low, false, flipped);
238 decode_subblock(pOut, r2, g2, b2, tableB, low, true, flipped);
239}
240
241typedef struct {
244 etc1_uint32 score; // Lower is more accurate
246
247static
249 if (a->score > b->score) {
250 *a = *b;
251 }
252}
253
254static
256 etc1_byte* pColors, bool flipped, bool second) {
257 int r = 0;
258 int g = 0;
259 int b = 0;
260
261 if (flipped) {
262 int by = 0;
263 if (second) {
264 by = 2;
265 }
266 for (int y = 0; y < 2; y++) {
267 int yy = by + y;
268 for (int x = 0; x < 4; x++) {
269 int i = x + 4 * yy;
270 if (inMask & (1 << i)) {
271 const etc1_byte* p = pIn + i * 3;
272 r += *(p++);
273 g += *(p++);
274 b += *(p++);
275 }
276 }
277 }
278 } else {
279 int bx = 0;
280 if (second) {
281 bx = 2;
282 }
283 for (int y = 0; y < 4; y++) {
284 for (int x = 0; x < 2; x++) {
285 int xx = bx + x;
286 int i = xx + 4 * y;
287 if (inMask & (1 << i)) {
288 const etc1_byte* p = pIn + i * 3;
289 r += *(p++);
290 g += *(p++);
291 b += *(p++);
292 }
293 }
294 }
295 }
296 pColors[0] = (etc1_byte)((r + 4) >> 3);
297 pColors[1] = (etc1_byte)((g + 4) >> 3);
298 pColors[2] = (etc1_byte)((b + 4) >> 3);
299}
300
301static
302inline int square(int x) {
303 return x * x;
304}
305
306static etc1_uint32 chooseModifier(const etc1_byte* pBaseColors,
307 const etc1_byte* pIn, etc1_uint32 *pLow, int bitIndex,
308 const int* pModifierTable) {
309 etc1_uint32 bestScore = ~0;
310 int bestIndex = 0;
311 int pixelR = pIn[0];
312 int pixelG = pIn[1];
313 int pixelB = pIn[2];
314 int r = pBaseColors[0];
315 int g = pBaseColors[1];
316 int b = pBaseColors[2];
317 for (int i = 0; i < 4; i++) {
318 int modifier = pModifierTable[i];
319 int decodedG = clamp(g + modifier);
320 etc1_uint32 score = (etc1_uint32) (6 * square(decodedG - pixelG));
321 if (score >= bestScore) {
322 continue;
323 }
324 int decodedR = clamp(r + modifier);
325 score += (etc1_uint32) (3 * square(decodedR - pixelR));
326 if (score >= bestScore) {
327 continue;
328 }
329 int decodedB = clamp(b + modifier);
330 score += (etc1_uint32) square(decodedB - pixelB);
331 if (score < bestScore) {
332 bestScore = score;
333 bestIndex = i;
334 }
335 }
336 etc1_uint32 lowMask = (((bestIndex >> 1) << 16) | (bestIndex & 1))
337 << bitIndex;
338 *pLow |= lowMask;
339 return bestScore;
340}
341
342static
344 etc_compressed* pCompressed, bool flipped, bool second,
345 const etc1_byte* pBaseColors, const int* pModifierTable) {
346 int score = pCompressed->score;
347 if (flipped) {
348 int by = 0;
349 if (second) {
350 by = 2;
351 }
352 for (int y = 0; y < 2; y++) {
353 int yy = by + y;
354 for (int x = 0; x < 4; x++) {
355 int i = x + 4 * yy;
356 if (inMask & (1 << i)) {
357 score += chooseModifier(pBaseColors, pIn + i * 3,
358 &pCompressed->low, yy + x * 4, pModifierTable);
359 }
360 }
361 }
362 } else {
363 int bx = 0;
364 if (second) {
365 bx = 2;
366 }
367 for (int y = 0; y < 4; y++) {
368 for (int x = 0; x < 2; x++) {
369 int xx = bx + x;
370 int i = xx + 4 * y;
371 if (inMask & (1 << i)) {
372 score += chooseModifier(pBaseColors, pIn + i * 3,
373 &pCompressed->low, y + xx * 4, pModifierTable);
374 }
375 }
376 }
377 }
378 pCompressed->score = score;
379}
380
381static bool inRange4bitSigned(int color) {
382 return color >= -4 && color <= 3;
383}
384
385static void etc_encodeBaseColors(etc1_byte* pBaseColors,
386 const etc1_byte* pColors, etc_compressed* pCompressed) {
387 int r1, g1, b1, r2, g2, b2; // 8 bit base colors for sub-blocks
388 bool differential;
389
390 int r51 = convert8To5(pColors[0]);
391 int g51 = convert8To5(pColors[1]);
392 int b51 = convert8To5(pColors[2]);
393 int r52 = convert8To5(pColors[3]);
394 int g52 = convert8To5(pColors[4]);
395 int b52 = convert8To5(pColors[5]);
396
397 r1 = convert5To8(r51);
398 g1 = convert5To8(g51);
399 b1 = convert5To8(b51);
400
401 int dr = r52 - r51;
402 int dg = g52 - g51;
403 int db = b52 - b51;
404
405 differential = inRange4bitSigned(dr) && inRange4bitSigned(dg)
407 if (differential) {
408 r2 = convert5To8(r51 + dr);
409 g2 = convert5To8(g51 + dg);
410 b2 = convert5To8(b51 + db);
411 pCompressed->high |= (r51 << 27) | ((7 & dr) << 24) | (g51 << 19)
412 | ((7 & dg) << 16) | (b51 << 11) | ((7 & db) << 8) | 2;
413 } else {
414 int r41 = convert8To4(pColors[0]);
415 int g41 = convert8To4(pColors[1]);
416 int b41 = convert8To4(pColors[2]);
417 int r42 = convert8To4(pColors[3]);
418 int g42 = convert8To4(pColors[4]);
419 int b42 = convert8To4(pColors[5]);
420 r1 = convert4To8(r41);
421 g1 = convert4To8(g41);
422 b1 = convert4To8(b41);
423 r2 = convert4To8(r42);
424 g2 = convert4To8(g42);
425 b2 = convert4To8(b42);
426 pCompressed->high |= (r41 << 28) | (r42 << 24) | (g41 << 20) | (g42
427 << 16) | (b41 << 12) | (b42 << 8);
428 }
429 pBaseColors[0] = r1;
430 pBaseColors[1] = g1;
431 pBaseColors[2] = b1;
432 pBaseColors[3] = r2;
433 pBaseColors[4] = g2;
434 pBaseColors[5] = b2;
435}
436
437static
439 const etc1_byte* pColors, etc_compressed* pCompressed, bool flipped) {
440 pCompressed->score = ~0;
441 pCompressed->high = (flipped ? 1 : 0);
442 pCompressed->low = 0;
443
444 etc1_byte pBaseColors[6];
445
446 etc_encodeBaseColors(pBaseColors, pColors, pCompressed);
447
448 int originalHigh = pCompressed->high;
449
450 const int* pModifierTable = kModifierTable;
451 for (int i = 0; i < 8; i++, pModifierTable += 4) {
452 etc_compressed temp;
453 temp.score = 0;
454 temp.high = originalHigh | (i << 5);
455 temp.low = 0;
456 etc_encode_subblock_helper(pIn, inMask, &temp, flipped, false,
457 pBaseColors, pModifierTable);
458 take_best(pCompressed, &temp);
459 }
460 pModifierTable = kModifierTable;
461 etc_compressed firstHalf = *pCompressed;
462 for (int i = 0; i < 8; i++, pModifierTable += 4) {
463 etc_compressed temp;
464 temp.score = firstHalf.score;
465 temp.high = firstHalf.high | (i << 2);
466 temp.low = firstHalf.low;
467 etc_encode_subblock_helper(pIn, inMask, &temp, flipped, true,
468 pBaseColors + 3, pModifierTable);
469 if (i == 0) {
470 *pCompressed = temp;
471 } else {
472 take_best(pCompressed, &temp);
473 }
474 }
475}
476
478 pOut[0] = (etc1_byte) (d >> 24);
479 pOut[1] = (etc1_byte)((d >> 16) & 0xFF);
480 pOut[2] = (etc1_byte)((d >> 8) & 0xFF);
481 pOut[3] = (etc1_byte)((d >> 0) & 0xFF);
482}
483
484// Input is a 4 x 4 square of 3-byte pixels in form R, G, B
485// inmask is a 16-bit mask where bit (1 << (x + y * 4)) tells whether the corresponding (x,y)
486// pixel is valid or not. Invalid pixel color values are ignored when compressing.
487// Output is an ETC1 compressed version of the data.
488
490 etc1_byte* pOut) {
491 etc1_byte colors[6];
492 etc1_byte flippedColors[6];
493 etc_average_colors_subblock(pIn, inMask, colors, false, false);
494 etc_average_colors_subblock(pIn, inMask, colors + 3, false, true);
495 etc_average_colors_subblock(pIn, inMask, flippedColors, true, false);
496 etc_average_colors_subblock(pIn, inMask, flippedColors + 3, true, true);
497
499 etc_encode_block_helper(pIn, inMask, colors, &a, false);
500 etc_encode_block_helper(pIn, inMask, flippedColors, &b, true);
501 take_best(&a, &b);
502 writeBigEndian(pOut, a.high);
503 writeBigEndian(pOut + 4, a.low);
504}
505
506// Return the size of the encoded image data (does not include size of PKM header).
507
509 return (((width + 3) & ~3) * ((height + 3) & ~3)) >> 1;
510}
511
512// Encode an entire image.
513// pIn - pointer to the image data. Formatted such that the Red component of
514// pixel (x,y) is at pIn + pixelSize * x + stride * y + redOffset;
515// pOut - pointer to encoded data. Must be large enough to store entire encoded image.
516
518 etc1_uint32 pixelSize, etc1_uint32 stride, etc1_byte* pOut) {
519 if (pixelSize < 2 || pixelSize > 3) {
520 return -1;
521 }
522 static const unsigned short kYMask[] = { 0x0, 0xf, 0xff, 0xfff, 0xffff };
523 static const unsigned short kXMask[] = { 0x0, 0x1111, 0x3333, 0x7777,
524 0xffff };
527
528 etc1_uint32 encodedWidth = (width + 3) & ~3;
529 etc1_uint32 encodedHeight = (height + 3) & ~3;
530
531 for (etc1_uint32 y = 0; y < encodedHeight; y += 4) {
532 etc1_uint32 yEnd = height - y;
533 if (yEnd > 4) {
534 yEnd = 4;
535 }
536 int ymask = kYMask[yEnd];
537 for (etc1_uint32 x = 0; x < encodedWidth; x += 4) {
538 etc1_uint32 xEnd = width - x;
539 if (xEnd > 4) {
540 xEnd = 4;
541 }
542 int mask = ymask & kXMask[xEnd];
543 for (etc1_uint32 cy = 0; cy < yEnd; cy++) {
544 etc1_byte* q = block + (cy * 4) * 3;
545 const etc1_byte* p = pIn + pixelSize * x + stride * (y + cy);
546 if (pixelSize == 3) {
547 memcpy(q, p, xEnd * 3);
548 } else {
549 for (etc1_uint32 cx = 0; cx < xEnd; cx++) {
550 int pixel = (p[1] << 8) | p[0];
551 *q++ = convert5To8(pixel >> 11);
552 *q++ = convert6To8(pixel >> 5);
553 *q++ = convert5To8(pixel);
554 p += pixelSize;
555 }
556 }
557 }
558 etc1_encode_block(block, mask, encoded);
559 memcpy(pOut, encoded, sizeof(encoded));
560 pOut += sizeof(encoded);
561 }
562 }
563 return 0;
564}
565
566// Decode an entire image.
567// pIn - pointer to encoded data.
568// pOut - pointer to the image data. Will be written such that the Red component of
569// pixel (x,y) is at pIn + pixelSize * x + stride * y + redOffset. Must be
570// large enough to store entire image.
571
572
575 etc1_uint32 pixelSize, etc1_uint32 stride) {
576 if (pixelSize < 2 || pixelSize > 3) {
577 return -1;
578 }
580
581 etc1_uint32 encodedWidth = (width + 3) & ~3;
582 etc1_uint32 encodedHeight = (height + 3) & ~3;
583
584 for (etc1_uint32 y = 0; y < encodedHeight; y += 4) {
585 etc1_uint32 yEnd = height - y;
586 if (yEnd > 4) {
587 yEnd = 4;
588 }
589 for (etc1_uint32 x = 0; x < encodedWidth; x += 4) {
590 etc1_uint32 xEnd = width - x;
591 if (xEnd > 4) {
592 xEnd = 4;
593 }
594 etc1_decode_block(pIn, block);
596 for (etc1_uint32 cy = 0; cy < yEnd; cy++) {
597 const etc1_byte* q = block + (cy * 4) * 3;
598 etc1_byte* p = pOut + pixelSize * x + stride * (y + cy);
599 if (pixelSize == 3) {
600 memcpy(p, q, xEnd * 3);
601 } else {
602 for (etc1_uint32 cx = 0; cx < xEnd; cx++) {
603 etc1_byte r = *q++;
604 etc1_byte g = *q++;
605 etc1_byte b = *q++;
606 etc1_uint32 pixel = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
607 *p++ = (etc1_byte) pixel;
608 *p++ = (etc1_byte) (pixel >> 8);
609 }
610 }
611 }
612 }
613 }
614 return 0;
615}
616
617static const char kMagic[] = { 'P', 'K', 'M', ' ', '1', '0' };
618
624
626
628 pOut[0] = (etc1_byte) (data >> 8);
629 pOut[1] = (etc1_byte) data;
630}
631
633 return (pIn[0] << 8) | pIn[1];
634}
635
636// Format a PKM header
637
639 memcpy(pHeader, kMagic, sizeof(kMagic));
640 etc1_uint32 encodedWidth = (width + 3) & ~3;
641 etc1_uint32 encodedHeight = (height + 3) & ~3;
643 writeBEUint16(pHeader + ETC1_PKM_ENCODED_WIDTH_OFFSET, encodedWidth);
644 writeBEUint16(pHeader + ETC1_PKM_ENCODED_HEIGHT_OFFSET, encodedHeight);
647}
648
649// Check if a PKM header is correctly formatted.
650
652 if (memcmp(pHeader, kMagic, sizeof(kMagic))) {
653 return false;
654 }
660 return format == ETC1_RGB_NO_MIPMAPS &&
661 encodedWidth >= width && encodedWidth - width < 4 &&
662 encodedHeight >= height && encodedHeight - height < 4;
663}
664
665// Read the image width from a PKM header
666
668 return readBEUint16(pHeader + ETC1_PKM_WIDTH_OFFSET);
669}
670
671// Read the image height from a PKM header
672
674 return readBEUint16(pHeader + ETC1_PKM_HEIGHT_OFFSET);
675}
SI F table(const skcms_Curve *curve, F v)
DlColor color
static void etc_encode_block_helper(const etc1_byte *pIn, etc1_uint32 inMask, const etc1_byte *pColors, etc_compressed *pCompressed, bool flipped)
Definition: etc1.cpp:438
static void writeBEUint16(etc1_byte *pOut, etc1_uint32 data)
Definition: etc1.cpp:627
static int convert4To8(int b)
Definition: etc1.cpp:135
etc1_uint32 etc1_pkm_get_height(const etc1_byte *pHeader)
Definition: etc1.cpp:673
static const int kLookup[8]
Definition: etc1.cpp:128
static const int kModifierTable[]
Definition: etc1.cpp:118
static int divideBy255(int d)
Definition: etc1.cpp:153
static const etc1_uint32 ETC1_PKM_ENCODED_HEIGHT_OFFSET
Definition: etc1.cpp:621
static bool inRange4bitSigned(int color)
Definition: etc1.cpp:381
static const etc1_uint32 ETC1_PKM_FORMAT_OFFSET
Definition: etc1.cpp:619
static int convert5To8(int b)
Definition: etc1.cpp:141
static const etc1_uint32 ETC1_PKM_WIDTH_OFFSET
Definition: etc1.cpp:622
static etc1_uint32 chooseModifier(const etc1_byte *pBaseColors, const etc1_byte *pIn, etc1_uint32 *pLow, int bitIndex, const int *pModifierTable)
Definition: etc1.cpp:306
static int convert8To5(int b)
Definition: etc1.cpp:164
static int convert6To8(int b)
Definition: etc1.cpp:147
static void writeBigEndian(etc1_byte *pOut, etc1_uint32 d)
Definition: etc1.cpp:477
void etc1_encode_block(const etc1_byte *pIn, etc1_uint32 inMask, etc1_byte *pOut)
Definition: etc1.cpp:489
static int convertDiff(int base, int diff)
Definition: etc1.cpp:170
static const etc1_uint32 ETC1_PKM_ENCODED_WIDTH_OFFSET
Definition: etc1.cpp:620
void etc1_pkm_format_header(etc1_byte *pHeader, etc1_uint32 width, etc1_uint32 height)
Definition: etc1.cpp:638
etc1_bool etc1_pkm_is_valid(const etc1_byte *pHeader)
Definition: etc1.cpp:651
void etc1_decode_block(const etc1_byte *pIn, etc1_byte *pOut)
Definition: etc1.cpp:208
static etc1_uint32 readBEUint16(const etc1_byte *pIn)
Definition: etc1.cpp:632
static const etc1_uint32 ETC1_RGB_NO_MIPMAPS
Definition: etc1.cpp:625
static void etc_encodeBaseColors(etc1_byte *pBaseColors, const etc1_byte *pColors, etc_compressed *pCompressed)
Definition: etc1.cpp:385
static int square(int x)
Definition: etc1.cpp:302
etc1_uint32 etc1_get_encoded_data_size(etc1_uint32 width, etc1_uint32 height)
Definition: etc1.cpp:508
static etc1_byte clamp(int x)
Definition: etc1.cpp:130
static void decode_subblock(etc1_byte *pOut, int r, int g, int b, const int *table, etc1_uint32 low, bool second, bool flipped)
Definition: etc1.cpp:175
static const etc1_uint32 ETC1_PKM_HEIGHT_OFFSET
Definition: etc1.cpp:623
etc1_uint32 etc1_pkm_get_width(const etc1_byte *pHeader)
Definition: etc1.cpp:667
static void etc_encode_subblock_helper(const etc1_byte *pIn, etc1_uint32 inMask, etc_compressed *pCompressed, bool flipped, bool second, const etc1_byte *pBaseColors, const int *pModifierTable)
Definition: etc1.cpp:343
static const char kMagic[]
Definition: etc1.cpp:617
static int convert8To4(int b)
Definition: etc1.cpp:158
int etc1_decode_image(const etc1_byte *pIn, etc1_byte *pOut, etc1_uint32 width, etc1_uint32 height, etc1_uint32 pixelSize, etc1_uint32 stride)
Definition: etc1.cpp:573
static void etc_average_colors_subblock(const etc1_byte *pIn, etc1_uint32 inMask, etc1_byte *pColors, bool flipped, bool second)
Definition: etc1.cpp:255
int etc1_encode_image(const etc1_byte *pIn, etc1_uint32 width, etc1_uint32 height, etc1_uint32 pixelSize, etc1_uint32 stride, etc1_byte *pOut)
Definition: etc1.cpp:517
static void take_best(etc_compressed *a, const etc_compressed *b)
Definition: etc1.cpp:248
#define ETC1_ENCODED_BLOCK_SIZE
Definition: etc1.h:26
#define ETC1_DECODED_BLOCK_SIZE
Definition: etc1.h:27
unsigned char etc1_byte
Definition: etc1.h:33
unsigned int etc1_uint32
Definition: etc1.h:35
int etc1_bool
Definition: etc1.h:34
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
Definition: main.cc:19
static bool b
struct MyStruct a[10]
uint32_t uint32_t * format
double y
double x
PODArray< SkColor > colors
Definition: SkRecords.h:276
int32_t height
int32_t width
SeparatedVector2 offset
etc1_uint32 score
Definition: etc1.cpp:244
etc1_uint32 low
Definition: etc1.cpp:243
etc1_uint32 high
Definition: etc1.cpp:242
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63