1+ //
2+ // Created by Radzivon Bartoshyk on 05/09/2023.
3+ //
4+
5+ #include " rgb1010102.h"
6+ #include < vector>
7+
8+ void convertRGBA1010102ToU16_C (const uint8_t *src, int srcStride, uint16_t *dst, int dstStride,
9+ int width, int height) {
10+ auto mDstPointer = reinterpret_cast <uint8_t *>(dst);
11+ auto mSrcPointer = reinterpret_cast <const uint8_t *>(src);
12+
13+ uint32_t testValue = 0x01020304 ;
14+ auto testBytes = reinterpret_cast <uint8_t *>(&testValue);
15+
16+ bool littleEndian = false ;
17+ if (testBytes[0 ] == 0x04 ) {
18+ littleEndian = true ;
19+ } else if (testBytes[0 ] == 0x01 ) {
20+ littleEndian = false ;
21+ }
22+
23+ for (int y = 0 ; y < height; ++y) {
24+
25+ auto dstPointer = reinterpret_cast <uint8_t *>(mDstPointer );
26+ auto srcPointer = reinterpret_cast <const uint8_t *>(mSrcPointer );
27+
28+ for (int x = 0 ; x < width; ++x) {
29+ uint32_t rgba1010102 = reinterpret_cast <const uint32_t *>(srcPointer)[0 ];
30+
31+ const uint32_t mask = (1u << 10u ) - 1u ;
32+ uint32_t b = (rgba1010102) & mask;
33+ uint32_t g = (rgba1010102 >> 10 ) & mask;
34+ uint32_t r = (rgba1010102 >> 20 ) & mask;
35+
36+ uint32_t a1 = (rgba1010102 >> 30 );
37+ uint32_t a = (a1 << 8 ) | (a1 << 6 ) | (a1 << 4 ) | (a1 << 2 ) | a1;
38+
39+ // Convert each channel to floating-point values
40+ auto rFloat = static_cast <uint16_t >(r);
41+ auto gFloat = static_cast <uint16_t >(g);
42+ auto bFloat = static_cast <uint16_t >(b);
43+ auto aFloat = static_cast <uint16_t >(a);
44+
45+ auto dstCast = reinterpret_cast <uint16_t *>(dstPointer);
46+ if (littleEndian) {
47+ dstCast[0 ] = bFloat;
48+ dstCast[1 ] = gFloat ;
49+ dstCast[2 ] = rFloat;
50+ dstCast[3 ] = aFloat;
51+ } else {
52+ dstCast[0 ] = rFloat;
53+ dstCast[1 ] = gFloat ;
54+ dstCast[2 ] = bFloat;
55+ dstCast[3 ] = aFloat;
56+ }
57+
58+ srcPointer += 4 ;
59+ dstPointer += 8 ;
60+ }
61+
62+ mSrcPointer += srcStride;
63+ mDstPointer += dstStride;
64+ }
65+ }
66+
67+ void convertRGBA1010102ToU8_C (const uint8_t *src, int srcStride, uint8_t *dst, int dstStride,
68+ int width, int height) {
69+ auto mDstPointer = reinterpret_cast <uint8_t *>(dst);
70+ auto mSrcPointer = reinterpret_cast <const uint8_t *>(src);
71+
72+ uint32_t testValue = 0x01020304 ;
73+ auto testBytes = reinterpret_cast <uint8_t *>(&testValue);
74+
75+ bool littleEndian = false ;
76+ if (testBytes[0 ] == 0x04 ) {
77+ littleEndian = true ;
78+ } else if (testBytes[0 ] == 0x01 ) {
79+ littleEndian = false ;
80+ }
81+
82+ for (int y = 0 ; y < height; ++y) {
83+
84+ auto dstPointer = reinterpret_cast <uint8_t *>(mDstPointer );
85+ auto srcPointer = reinterpret_cast <const uint8_t *>(mSrcPointer );
86+
87+ for (int x = 0 ; x < width; ++x) {
88+ uint32_t rgba1010102 = reinterpret_cast <const uint32_t *>(srcPointer)[0 ];
89+
90+ const uint32_t mask = (1u << 10u ) - 1u ;
91+ uint32_t b = (rgba1010102) & mask;
92+ uint32_t g = (rgba1010102 >> 10 ) & mask;
93+ uint32_t r = (rgba1010102 >> 20 ) & mask;
94+
95+ uint32_t a1 = (rgba1010102 >> 30 );
96+ uint32_t a = (a1 << 8 ) | (a1 << 6 ) | (a1 << 4 ) | (a1 << 2 ) | a1;
97+
98+ // Convert each channel to floating-point values
99+ auto rFloat = std::max (std::min (static_cast <uint8_t >((r * 255 ) / 1023 ), (uint8_t ) 255 ),
100+ (uint8_t ) 0 );
101+ auto gFloat = std::max (std::min (static_cast <uint8_t >((g * 255 ) / 1023 ), (uint8_t ) 255 ),
102+ (uint8_t ) 0 );
103+ auto bFloat = std::max (std::min (static_cast <uint8_t >((b * 255 ) / 1023 ), (uint8_t ) 255 ),
104+ (uint8_t ) 0 );
105+ auto aFloat = std::max (std::min (static_cast <uint8_t >((a * 255 ) / 1023 ), (uint8_t ) 255 ),
106+ (uint8_t ) 0 );
107+
108+ auto dstCast = reinterpret_cast <uint8_t *>(dstPointer);
109+ if (littleEndian) {
110+ dstCast[0 ] = bFloat;
111+ dstCast[1 ] = gFloat ;
112+ dstCast[2 ] = rFloat;
113+ dstCast[3 ] = aFloat;
114+ } else {
115+ dstCast[0 ] = rFloat;
116+ dstCast[1 ] = gFloat ;
117+ dstCast[2 ] = bFloat;
118+ dstCast[3 ] = aFloat;
119+ }
120+
121+ srcPointer += 4 ;
122+ dstPointer += 4 ;
123+ }
124+
125+ mSrcPointer += srcStride;
126+ mDstPointer += dstStride;
127+ }
128+ }
129+
130+ void RGBA1010102ToU8 (const uint8_t *src, int srcStride, uint8_t *dst, int dstStride,
131+ int width, int height) {
132+ convertRGBA1010102ToU8_C (src, srcStride, dst, dstStride, width, height);
133+ }
134+
135+ void RGBA1010102ToU16 (const uint8_t *src, int srcStride, uint16_t *dst, int dstStride,
136+ int width, int height) {
137+ convertRGBA1010102ToU16_C (src, srcStride, dst, dstStride, width, height);
138+ }
0 commit comments